arrow_backBack to Knowledge Base
Backend Architecture·Jun 14, 2025·11 MIN READ

Designing APIs That Survive Production Traffic

Strict API contracts, pagination, rate limiting, and defensive validation to ensure your services don't buckle under load.

api-designscalingrate-limiting

01.API Contracts Are Promises

Your API contract is a promise to every consumer. Breaking it silently — removing fields, changing data types, renaming endpoints — causes production outages in downstream services. Use versioned APIs (/v1/, /v2/) and deprecate old versions with sunset headers rather than deleting them. Generate OpenAPI specs and treat them as source of truth.

02.Pagination Is Not Optional

Any endpoint that returns a list must be paginated. Returning 50,000 records in a single response will crash your server, exhaust database connections, and timeout the client. Cursor-based pagination scales better than offset-based because it doesn't degrade with deep pages.

typescript
// Cursor-based pagination
async findDocuments(cursor?: string, limit = 20) {
  return this.repo.find({
    where: cursor ? { id: MoreThan(cursor) } : {},
    take: Math.min(limit, 100), // hard cap
    order: { id: 'ASC' },
  });
}

03.Defensive Input Validation

Every field coming from the client needs explicit validation — not just type checking, but business rule validation. String fields need max length limits. Numeric fields need range bounds. Enum fields need exhaustive validation. Without this, attackers can send 10MB JSON payloads, negative quantities, or SQL injection strings.

04.Idempotency Keys for Mutations

POST requests that create resources should accept an Idempotency-Key header. Store the key and its result in Redis with a short TTL. If the same key is received again, return the cached result instead of re-executing. This prevents duplicate orders, payments, or records when clients retry on network failures.

05.Health Checks & Circuit Breakers

Every service must expose a /health endpoint that checks database connectivity, Redis connectivity, and any external dependencies. Load balancers use this to route around unhealthy instances. Pair health checks with circuit breakers — if a downstream service fails 5 times in 10 seconds, stop calling it and return a fallback response.