Rate Limiter

Design a distributed API rate limiter for a public API platform.

00

Practice checkpoints

The requirements are open as a taste. From the numbers onward, the full guide opens in the app.

  1. 01
    Clarify scope
  2. 02
    Requirements + scale
  3. 03
    API + data modelUnlocks in the app
  4. 04
    Draw architectureUnlocks in the app
  5. 05
    Deep diveUnlocks in the app
  6. 06
    Trade-off decisionUnlocks in the app
01

Requirements that shape the design

Do not only state requirements. Ask for them. Each card pairs the design constraint with a clarification question you can say out loud before drawing the architecture.

Functional requirements

01What does a rejected request actually see?

HTTP 429 with Retry-After and X-RateLimit-Limit/Remaining headers — a well-behaved client can back off instead of hammering.

02Limited by what — user, API key, IP, endpoint?

All of them, per policy: each key type carries its own quota and window, and one request can be checked against several (user AND endpoint).

03Who owns the limiter — every service, or one layer?

One shared layer (gateway middleware or sidecar): services declare policies; the counting machinery exists exactly once.

04Do clients get warning before they hit the wall?

Yes: every response carries remaining-quota headers, so a well-built client self-throttles long before the first 429.

05A request matches several policies - which one answers?

All are checked and the most restrictive wins; the 429 names which limit tripped, because a debuggable rejection is part of the contract.

06Free tier and paid tier share this system?

Yes: policies key on tier attributes, and a tier upgrade changes the effective quota at the very next request - no cache to wait out.

Out of scopeBilling-grade usage metering (limits protect, they do not bill) · DDoS scrubbing at the network layer (L3/L4) · Per-tenant fairness scheduling inside services

Non-functional requirements

01How much latency can the check add?

About a millisecond: one atomic in-memory operation (local or one Redis round trip) — the limiter must never be the slow part.

02Two requests race for the last slot — what happens?

Exactly one passes: check-and-decrement is a single atomic operation (Redis Lua or equivalent), never read-then-write.

03The limiter goes down — do we block everything?

Fail-open with an alert: dropping rate protection briefly beats turning the limiter into a single point of failure.

04Same client, different gateway node — same answer?

Yes: counters live in a shared store keyed by client, not per node — otherwise N nodes silently mean N× quota.

05What about the window-edge burst?

Fixed windows allow 2× quota straddling the boundary; a sliding-window counter weights the previous window to smooth it at almost no memory cost.

Keep asking — the interview is a conversation

Real interviews probe far more than a tidy list. These are the scope questions that separate candidates who interrogate the problem from those who recite it.

  • Is the limit protecting infrastructure (protect mode) or enforcing a product quota (billing-adjacent)?
  • Per user, per key, per IP — and what about shared IPs (offices, CGNAT)?
  • Are bursts acceptable (token bucket) or must the rate be smooth (leaky bucket)?
  • Fail-open or fail-closed when the limiter itself degrades?
  • Do limits need to adapt to downstream health, or stay static?
01

Unlock the full playbook for Rate Limiter

Numbers, architecture diagram, API and data model, deep dives, expected topics, self-check, whiteboard starter, and common mistakes unlock inside the app.

02

Numbers that force architecture decisions

Locked in the app

03

Architecture path

Locked in the app

04

API and data model

Locked in the app

05

Deep dive directions

Locked in the app

+Series

Practice the related series