HLD · APIs
API Design & Rate Limiting
Expose reliable APIs and protect backends from abuse and overload.
Retry-After header.1. REST API design basics
- Resources as nouns:
GET /users/123,POST /orders - HTTP verbs: GET (read), POST (create), PUT/PATCH (update), DELETE
- Status codes: 200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests, 500 Server Error
- Versioning:
/v1/usersor headerAccept-Version - Pagination:
?cursor=abc&limit=20(preferred over offset at scale)
2. API Gateway role
Single entry point that handles:
- Authentication (JWT validation)
- Rate limiting & throttling
- Routing to microservices
- SSL termination, request logging, API keys
Examples: AWS API Gateway, Kong, NGINX, Envoy.
3. Why rate limiting
- Prevent abuse (scraping, brute force)
- Fair usage across tenants (free vs paid tier)
- Protect downstream (DB, payment provider caps)
- Cost control on serverless/metered APIs
Example: A login API may allow five attempts per minute for one account and IP address. Further attempts return 429 Too Many Requests and tell the client when to retry.
Sample HTTP 429 response
4. Rate limiting algorithms
Token bucket
Bucket holds tokens; refills at fixed rate. Each request consumes 1 token. Allows bursts up to bucket size.
Example: 100 tokens, refill 10/sec → user can burst 100, then steady 10 RPS.
Leaky bucket
Requests enter queue; processed at constant rate. Smooths bursts; excess dropped or queued.
Concrete example: A video-processing API accepts a burst of 20 jobs but releases only two jobs per second to GPU workers, preventing sudden overload.
Fixed window
Count requests per minute. Simple but boundary spike (59 at :59 + 60 at :00 = 119 in 2 seconds).
Sliding window
Count over rolling last 60 seconds. Smoother; slightly more state (Redis sorted sets).
5. Distributed rate limiting
When several API servers handle the same client, they need a shared counter. Redis can update that counter atomically with INCR and an expiry, or with a Lua script.
6. Idempotency for safe retries
Client sends Idempotency-Key: uuid on POST payment. Server stores result keyed by UUID — duplicate requests return same response without double charge.
7. GraphQL vs REST (brief)
REST: multiple endpoints, fixed payloads. GraphQL: single endpoint, client picks fields — flexible but harder to cache and rate-limit per resource.
Quick revision
- REST: Nouns, correct verbs, meaningful status codes, cursor pagination.
- Gateway: Auth, routing, rate limit, TLS at edge.
- Algorithms: Token bucket (bursts), sliding window (fair), leaky bucket (smooth).
- Distributed: Redis counters with TTL.
- 429: Return a clear error and a
Retry-Afterheader when possible. - Safe retries: Use idempotency keys for retryable create or payment requests.