Start with a contract
OpenAPI or GraphQL SDL — pick one, version it in git, generate clients from it. The contract is the most stable artifact in your system; everything else should follow it.
Pagination from day one
Even when a table only has 12 rows, paginate it. Cursor-based pagination beats offset for scale. The cursor should be opaque; do not leak the underlying column.
Rate limiting and quotas
- Per-tenant and per-token limits.
- Sliding window in Redis or your edge.
- 429 responses with
Retry-Afterand explanatory body.
Caching
The cheapest scaling tool you have. Cache:
- Read-heavy lookups behind Redis.
- Public assets behind a CDN.
- HTTP responses with
Cache-ControlandETagfor clients that respect them.
Idempotency
Mutating endpoints should accept an Idempotency-Key header. Store the result keyed by the idempotency key for at least 24 hours. Payments, signups, and webhook handlers especially.
Observability
Three things to ship together:
- Structured logs with
request_id,tenant_id,user_id. - Metrics (RED: rate, errors, duration) per endpoint.
- Traces with span propagation.
If you cannot answer "what did request X do?" in under a minute, you are flying blind.
Versioning
URL versioning (/v1/) is fine. Major versions are years apart; deprecate gradually with a Sunset header.
Outcomes
An API that handles 10x growth without a rewrite. Most of the cost is paid in the first two months and compounds for the next two years.