25. Rate Limiting
1
The picture to keep in your head2
25.1 Why limit?3
25.2 What are the algorithms?4
25.3 How do the algorithms compare?5
25.4 How does distributed rate limiting with Redis work?6
25.5 Where should the limiter go?7
25.6 What do 429 and rate-limit headers look like?8
25.7 How do you handle bots and abuse?9
Memory card and where the analogy breaks10
Practice: five levels11
Interview questions12
Solutions13
Sources14
Code lab25. Rate Limiting
25.6 What do 429 and rate-limit headers look like?
3 min read+10 XP
At the club: A good bouncer doesn't just say "no". They say "full, come back in 6 seconds", and the sign by the door shows how many passes are left.
In the system: When a client is over its limit, return 429 Too Many Requests with a clear body, and tell the client when to retry:
HTTP/1.1 429 Too Many Requests
Retry-After: 23
RateLimit-Limit: 100
RateLimit-Remaining: 0
RateLimit-Reset: 23
Content-Type: application/problem+json
{"title": "Rate limit exceeded", "status": 429,
"detail": "100 requests per minute on the free plan. Retry in 23 seconds."}
Retry-After(standard HTTP): seconds to wait, or a date.- Limit, remaining and reset headers on every response, not just the 429, so clients can slow down before hitting the wall. Many APIs use
X-RateLimit-*names (GitHub sendsx-ratelimit-limit,x-ratelimit-remainingandx-ratelimit-reset); an IETF draft standardisesRateLimitheader fields. - Document the limits per plan and endpoint. GitHub, for example, documents 5,000 requests an hour for authenticated users and 60 for unauthenticated ones.
Choices to make:
- 429 vs 503: 429 means "you are sending too much"; 503 means "we are overloaded" (load shedding, Chapter 29).
- Don't count rejected requests against the limit forever, or a misbehaving client never recovers; but do keep limits on 429 storms at the edge.
- Clients should respect Retry-After and add jitter, or all rejected clients return at the same second (Chapter 21's herd).
Memory code: "Say 'too many', say how many are left, and say when to come back."