32. Design a Rate Limiter as a Service
1
The interview prompt2
32.1 What do you ask first?3
32.2 How big is this, really?4
32.3 What are the doors?5
32.4 What do we store?6
32.5 What does the whole system look like?7
32.6 How do you pick the algorithm?8
32.7 How do counters work in Redis?9
32.8 What race conditions do you have to handle?10
32.9 How do limits work across regions?11
32.10 What would you say in the last five minutes?12
Score yourself13
Variations to practise14
Sources15
Code lab32. Design a Rate Limiter as a Service
32.3 What are the doors?
3 min read+10 XP
Step 3: API and data model (10 minutes)
POST /v1/check
body: { "rule": "partner-api", "key": "apikey_42", "cost": 1 }
returns: 200 { "allowed": true, "limit": 100, "remaining": 37, "reset_after_ms": 22800 }
200 { "allowed": false, "limit": 100, "remaining": 0, "retry_after_ms": 600 }
POST /v1/check/multi (one atomic check of several rules)
body: { "checks": [ {"rule": "login-ip", "key": "1.2.3.4"},
{"rule": "login-account", "key": "asha"} ] }
PUT /v1/rules/{rule_id} (admin; versioned, reviewed)
GET /v1/rules/{rule_id}/stats
The check returns 200 either way: "not allowed" is an answer, not an error. The caller turns it into a 429 with Retry-After and RateLimit-* headers (Chapter 25).
In practice the hot path is usually a client library or sidecar inside the caller, not an HTTP hop to a separate service: it caches the rules and talks to Redis directly, saving a round trip. The HTTP API exists for callers that can't embed the library.