system-design · intermediate

Design a Rate Limiter — Interview Walkthrough

Start here

A rate limiter enforces policies like:

“User 42 may call at most 100 requests per minute.”

It protects APIs from abuse, bugs, and noisy neighbors while keeping the system fair.

This interview classic tests whether you can clarify rules, pick an algorithm, place the component in an architecture, and scale it with shared state.

What you will learn

  1. Gather functional and non-functional requirements.
  2. Compare token bucket, leaky bucket, fixed and sliding windows.
  3. Place limiters at gateway vs service.
  4. Design distributed counters with Redis-style stores.
  5. Return correct HTTP semantics (429, headers).
  6. Discuss failure modes when the limiter store is down.

What you should know first

TopicWhy
Rate limiting algorithmsAlgorithm mechanics
API gatewayCommon placement
Answering frameworkInterview structure

Words you need before we begin

TermPlain English
QuotaAllowed amount in a period.
Token bucketTokens refill over time; requests spend tokens.
Fixed windowCount resets on clock boundaries.
Sliding windowSmoother rolling period approximation.
429HTTP Too Many Requests.
Hard vs soft limitReject vs delay/throttle.
Distributed limiterShared state across many servers.

Simple story: tickets for a ride

Riders get tickets over time. No ticket, no ride. Saving tickets allows a short burst. Staff may also smooth entry so people trickle in.

Requirements to clarify

Example numbers

High-level placement

flowchart LR
  Client --> GW[API gateway + limiter]
  GW -->|allow| Svc[Service]
  GW -->|deny 429| Client
  GW --> Store[(Redis counters)]

Edge placement stops bad traffic early. Service placement knows richer identity. Many systems do both (coarse edge + fine service).

Algorithm choice in interviews

AlgorithmSay this
Token bucketGood default: average rate + burst
Fixed windowSimple but boundary double-spend risk
Sliding window logAccurate, more memory
Sliding window counterPractical approximation
Leaky bucketSmooths to constant rate; may queue

Pick token bucket or sliding window counter and justify.

Distributed design steps

  1. Key design: rate:user:42:/search or similar.
  2. Atomic ops: Lua script or MULTI/INCR with TTL.
  3. Return remaining quota to client when possible.
  4. Shard Redis if needed; accept small inaccuracy if using local+global hybrid.
  5. Fail policy: fail open (risk overload) vs fail closed (safer for fragile deps)—state choice.

Complete worked example

Policy

Authenticated free tier: 60 requests/minute, burst 10, token bucket.

Redis sketch

Path

Gateway middleware runs limiter before routing. Health checks excluded. Admin routes separate higher limits.

Failure

Redis blip: for public marketing site maybe fail open with local emergency cap; for payments API fail closed.

Interview scoring signals

Failure modes

ModeImpactMitigation
Fixed window edge burst2× rateSliding/token bucket
Per-IP limits on NATPunish many usersPrefer user/API key
Unlimited retries on 429StormClient backoff; temporary bans
Limiter store downOpen or closed riskExplicit policy + local caps
One key for whole companyInternal noisy neighborTenant + key hierarchy

Trade-offs

ChoiceBenefitCost
Central RedisGlobal fairnessExtra hop, dependency
Local-only limitsFastWeak global guarantee
Strict accuracyFairnessComplexity/cost
ApproximateSpeed/scaleOccasional over-allow

Common misunderstandings

  1. “Rate limit equals security.” One layer only.
  2. “429 means stop forever.” Temporary; honor retry guidance.
  3. “Same limit for all routes.” Login/search often stricter.
  4. “More Redis nodes always keep exact global counts.” Need careful atomic design.
  5. “Token bucket forbids bursts.” Capacity is the burst.

Check your understanding

  1. What two numbers define a token bucket policy?
  2. Why place a limiter at the gateway?
  3. What is a fixed-window boundary problem?
  4. Fail open vs fail closed when Redis is down?
  5. Why exclude health checks?

Practice

  1. Design keys for user + route limits.
  2. Write a 429 response example with headers.
  3. Compare edge-only vs service-only enforcement.
  4. Estimate Redis QPS for 10k RPS with one INCR each.
  5. Role-play a 25-minute design interview.

Deeper production notes

Cost-based tokens

Charge more tokens for heavy endpoints. Document costs so SDKs can budget.

Hierarchy of limits

Global emergency brake + per-tenant + per-user. Prevents one dimension from being gamed.

Observability

Metrics: allowed, denied, store latency, top offenders (careful with PII).

Additional teaching scenarios

Scenario A — peak load day

Traffic multiplies by ten. Mark which failure modes appear first and the first mitigation for each.

Scenario B — mixed versions

Half the fleet runs an old build. Which assumptions break? Prefer one deploy window of compatibility.

Scenario C — five-sentence teach-back

Explain the core idea without acronyms using only the simple story and worked example.

Scenario D — metrics and alerts

List three metrics and one alert that track user impact or a scarce resource.

Scenario E — non-goals

Name two problems this technique should not solve.

Scenario F — ownership

Who owns dashboards, code, and pages? Blank means not ready for broad rollout.

Revision summary

Glossary

TermDefinition
Rate limiterComponent enforcing request rate policies.
Token bucketRefilling tokens authorizing requests.
Quota keyCounter identity (user/route/window).

Abbreviations and terminology

What to learn next

  1. Rate limiting algorithms
  2. Distributed rate limiting
  3. API gateway
  4. Design URL shortener

Extra teaching notes for first-time builders

Write the single bottleneck you are protecting before picking tools. Name the signal that tells you the design is working for users, not only that internal counters move. When reviewing a change related to this lesson, ask what happens when the component is slow for ten minutes, down entirely, or running twice. Prefer small explicit failure modes that operators can understand at 3 a.m.

Document ownership for dashboards, code, and pages. Undocumented mechanisms become folklore and then outages. Prefer designs that tolerate mixed versions for at least one deploy window so rollouts do not require perfect global simultaneity.

Napkin math helps: estimate peak rate, multiply by payload size, and ask whether the design still holds when a dependency is at half capacity. If the answer depends on luck, add bounds, backpressure, or shedding before production traffic arrives.

Extra teaching notes for first-time builders

Write the single bottleneck you are protecting before picking tools. Name the signal that tells you the design is working for users, not only that internal counters move. When reviewing a change related to this lesson, ask what happens when the component is slow for ten minutes, down entirely, or running twice. Prefer small explicit failure modes that operators can understand at 3 a.m.

Document ownership for dashboards, code, and pages. Undocumented mechanisms become folklore and then outages. Prefer designs that tolerate mixed versions for at least one deploy window so rollouts do not require perfect global simultaneity.

Napkin math helps: estimate peak rate, multiply by payload size, and ask whether the design still holds when a dependency is at half capacity. If the answer depends on luck, add bounds, backpressure, or shedding before production traffic arrives.

Extra teaching notes for first-time builders

Write the single bottleneck you are protecting before picking tools. Name the signal that tells you the design is working for users, not only that internal counters move. When reviewing a change related to this lesson, ask what happens when the component is slow for ten minutes, down entirely, or running twice. Prefer small explicit failure modes that operators can understand at 3 a.m.

Document ownership for dashboards, code, and pages. Undocumented mechanisms become folklore and then outages. Prefer designs that tolerate mixed versions for at least one deploy window so rollouts do not require perfect global simultaneity.

Napkin math helps: estimate peak rate, multiply by payload size, and ask whether the design still holds when a dependency is at half capacity. If the answer depends on luck, add bounds, backpressure, or shedding before production traffic arrives.

Extra teaching notes for first-time builders

Write the single bottleneck you are protecting before picking tools. Name the signal that tells you the design is working for users, not only that internal counters move. When reviewing a change related to this lesson, ask what happens when the component is slow for ten minutes, down entirely, or running twice. Prefer small explicit failure modes that operators can understand at 3 a.m.

Document ownership for dashboards, code, and pages. Undocumented mechanisms become folklore and then outages. Prefer designs that tolerate mixed versions for at least one deploy window so rollouts do not require perfect global simultaneity.

Napkin math helps: estimate peak rate, multiply by payload size, and ask whether the design still holds when a dependency is at half capacity. If the answer depends on luck, add bounds, backpressure, or shedding before production traffic arrives.

FAQ from first-time learners

Q: Is API gateway enough?
A: Great start; some limits need service-level context.

Q: Token bucket or sliding window?
A: Either is defensible—explain burst needs.

Q: Local memory limiter?
A: OK for single instance; weak for horizontal scale.

By Shubham Jain

All articles · Study paths

Shubham Jain · Learning Lab