Question presented to candidate: "Design the rate limiter for our public API. Requests arrive at a fleet of gateway servers; customers have plans with different limits per API key, and we also want per-IP limits against abuse. Walk me through where it runs, what state it keeps, how the gateways share that state, and what happens when the limiter itself fails."
What a strong answer should cover:
- Requirements first: what is limited (API key, user, IP, endpoint), the rules and their source, accuracy needed, latency budget (a limiter check must cost about a millisecond), availability
- Placement: a middleware in the API gateway (or edge), keyed per client and rule, returning 429 with
Retry-Afterand remaining-budget headers; client-side and per-service limits as extra layers - Algorithm choice with a reason (usually token bucket, sliding log for small exact limits) and a rules store pushed to gateways
- Shared state: local-only limits are wrong when traffic is uneven across nodes; a central store (Redis, sharded by key, atomic Lua) is exact but costs a round trip per request; local batching / token leases cut store calls at some accuracy cost
- Failure policy: fail open vs fail closed, timeouts, a local fallback limit; multi-region choices
- Capacity numbers (requests per second, keys, memory, Redis shards) and what breaks first at 10x
Clarifying questions expected:
- Is the limit hard (billing, abuse) or soft (fairness), and how much over-admission is acceptable?
- How many requests per second at peak, how many distinct keys, and how many regions?
- Should a limiter outage allow or reject traffic?
Code / implementation expected: Optional โ high-level design with numbers; the example simulates gateways sharing a token bucket and the limiter store failing.