๐ญ๐ฌ ๐๐ฃ๐ ๐ฎ๐ป๐ฑ ๐๐ฎ๐๐ฎ๐ฏ๐ฎ๐๐ฒ ๐ ๐ถ๐๐๐ฎ๐ธ๐ฒ๐ ๐๐ฒ๐ณ๐ผ๐ฟ๐ฒ ๐ฃ๐ฟ๐ผ๐ฑ๐๐ฐ๐๐ถ๐ผ๐ป
You wrote your first API. It works on your machine. Then you deploy to production and everything breaks.
I have seen this happen many times. Most mistakes are predictable. You can avoid them if you know what to look for.
Here are 10 common blunders and how to fix them.
๐ญ. ๐ ๐ถ๐๐๐ถ๐ป๐ด ๐๐ฑ๐ฒ๐บ๐ฝ๐ผ๐๐ฒ๐ป๐ฐ๐ A user clicks "Pay" twice because their signal drops. Without protection, you charge them twice.
- The Fix: Use an Idempotency-Key header.
- The Process: The client sends a unique UUID. The server checks if it has seen that key. If yes, return the stored response. If no, process the request and save the result.
๐ฎ. ๐ข๐ณ๐ณ๐๐ฒ๐ ๐ฃ๐ฎ๐ด๐ถ๐ป๐ฎ๐๐ถ๐ผ๐ป Using LIMIT and OFFSET is slow on large tables. The database must scan and discard every row before the offset.
- The Fix: Use cursor-based pagination.
- The Process: Use the last seen ID or timestamp to find the next set of results. This stays fast even with millions of rows.
๐ฏ. ๐ก๐ผ ๐๐ฃ๐ ๐ฉ๐ฒ๐ฟ๐๐ถ๐ผ๐ป๐ถ๐ป๐ด Changing an endpoint without a version number breaks every client using your API.
- The Fix: Use URL versioning from day one.
- Example: Use /v1/users instead of /users.
๐ฐ. ๐๐ฎ๐ฑ ๐๐ฟ๐ฟ๐ผ๐ฟ ๐ฅ๐ฒ๐๐ฝ๐ผ๐ป๐๐ฒ๐ Vague errors make debugging hard.
- The Fix: Use consistent error envelopes.
- The Process: Include an error code, a clear message, and a request_id. This helps you find the exact log entry quickly.
๐ฑ. ๐๐ป๐ฐ๐ผ๐ป๐๐ถ๐๐๐ฒ๐ป๐ ๐ก๐ฎ๐บ๐ถ๐ป๐ด Mixing snake_case and camelCase frustrates developers.
- The Fix: Pick one convention and enforce it with a linter.
๐ฒ. ๐จ๐ป๐ป๐ฒ๐ฐ๐ฒ๐๐๐ฎ๐ฟ๐ ๐๐ฒ๐ป๐ผ๐ฟ๐บ๐ฎ๐น๐ถ๐๐ฎ๐๐ถ๐ผ๐ป Copying data to avoid JOINs causes data integrity issues.
- The Fix: Normalize your data first.
- Only denormalize when profiling shows a clear performance bottleneck.
๐ณ. ๐๐ฎ๐ฑ ๐๐ป๐ฑ๐ฒ๐ ๐ถ๐ป๐ด Too few indexes make queries slow. Too many indexes make writes slow.
- The Fix: Index your primary keys and every foreign key.
- Do not use functions on indexed columns in your WHERE clause.
๐ด. ๐ง๐ต๐ฒ ๐ก+๐ญ ๐ค๐๐ฒ๐ฟ๐ ๐ฃ๐ฟ๐ผ๐ฏ๐น๐ฒ๐บ Running one query to get a list, then one query per item in that list, kills performance.
- The Fix: Use batch loading. Fetch all related data in a single query using an IN clause.
๐ต. ๐๐น๐ผ๐ฐ๐ธ๐ถ๐ป๐ด ๐ฆ๐ฐ๐ต๐ฒ๐บ๐ฎ ๐๐ต๐ฎ๐ป๐ด๐ฒ๐ Running ALTER TABLE on a massive table can lock it for hours. This causes outages.
- The Fix: Use an expand and contract pattern.
- The Process: Add the new column first. Backfill data in small batches. Switch reads to the new column. Finally, drop the old column.
๐ญ๐ฌ. ๐๐ฟ๐ฒ๐ฎ๐ธ๐ถ๐ป๐ด ๐๐ต๐ฎ๐ป๐ด๐ฒ๐ ๐๐ต๐ฎ๐ ๐ฑ๐ผ๐ป'๐ ๐น๐ผ๐ผ๐ธ ๐น๐ถ๐ธ๐ฒ ๐ถ๐ Changing a timestamp format or a validation limit is a breaking change.
- The Fix: Treat any change to the response shape as a version update.
Which mistake did you learn the hard way? Tell me in the comments.