Rate Limiter System Design Interview: Reasoning Out Loud
A step-by-step walkthrough of a rate limiter system design interview, from clarifying requirements to naming trade-offs out loud, so you practise the reasoning interviewers score.
A rate limiter system design interview is not a test of whether you can recall one algorithm. It is a test of whether you can take a vague prompt, turn it into agreed requirements, pick an approach, and explain out loud why you picked it. The walkthrough below follows the conversation rather than a single correct answer, so you can rehearse the reasoning and the narration at the same time.
Why Rate Limiter Comes Up So Often
A rate limiter is small enough to finish in one interview slot but it touches distributed systems fundamentals: shared state, atomicity, consistency, failure modes and scale. That combination makes it a useful probe.
Interviewers use it to see how you handle ambiguity, how you reason about scale, and how you behave when a component fails. They are not checking whether you memorised one algorithm. There are several defensible designs, and the interviewer knows it.
So treat the session as a walkthrough of the conversation. You are being scored on the reasoning you make visible, the questions you ask, and the trade-offs you name. A tidy diagram with no commentary scores worse than a rough diagram with clear thinking attached to it.
Step 1: Clarify Requirements Before You Design
In a rate limiter system design interview, resist the urge to start drawing. Spend the first few minutes asking questions, and write the answers down where the interviewer can see them.
Ask who the clients are. Internal services calling each other behave differently from public API users, and both together is a third case. Ask what is being limited: requests per user, per API key, per IP, or per endpoint. These give you different key shapes and different fairness properties.
Ask about the limit shape. Do they want a hard ceiling per window, or are short bursts acceptable as long as the average holds? Ask what should happen when the limiter's own store is unavailable: should it fail open, letting traffic through, or fail closed, rejecting requests?
Then write the agreed requirements back in one or two sentences before moving on. Something like: "So we are limiting public API keys to a steady average rate with small bursts allowed, and if our counter store is down we fail open and log it." That sentence is your contract for the rest of the interview.
Step 2: State the Functional and Non-Functional Requirements
Keep this section short. It is a contract, not the design.
Functionally, the system decides whether a request is allowed, returns a clear signal when it is not, and exposes remaining quota so clients can plan. Non-functionally, it adds very little latency to every request, stays available, scales horizontally, and behaves predictably under bursts.
Then call out what is out of scope. Say plainly that you are not designing the billing system, the authentication layer, or the analytics pipeline. Naming exclusions tells the interviewer your choices are deliberate rather than forgetful.
Step 3: Choose a Counting Approach and Say Why
This is where many candidates list options without judgement. Instead, state the trade-off in one sentence for each option you consider, then commit to one.
The main options
Fixed window is the simplest: count requests per key per time bucket and reset at the boundary. It is easy to reason about, but it allows burst traffic at window boundaries, because a client can spend a full quota at the end of one window and another at the start of the next.
Sliding window log stores a timestamp per request and counts those inside the trailing window. It is accurate, but memory heavy at high cardinality, because you keep one entry per request per key.
Sliding window counter blends the current and previous window counts by how far into the window you are. It is a practical middle ground for most API limits, trading a little accuracy for a large reduction in memory.
Token bucket refills tokens at a steady rate and allows a request while tokens remain. It is a good fit when you want to allow short bursts while enforcing an average rate.
Leaky bucket drains at a fixed rate, which suits a smooth, steady outflow where you would rather queue or drop than burst.
How to say it out loud
A workable script: "For a public API key limit where occasional bursts are fine, I would start with token bucket because it expresses both a burst allowance and an average rate in two parameters. If the interviewer wanted strict per-window fairness instead, sliding window counter would be my next choice."
That sentence does three things. It states a choice, gives a reason, and shows you know what would change your mind. In a rate limiter system design interview, that pattern is the whole game.
Step 4: Sketch the Architecture
Start by deciding where the limiter sits, and say the reason out loud. In the client is easy to bypass. In a sidecar keeps it close to the service but duplicates state. In the gateway centralises enforcement for everything behind it. As a shared service it can be reused by many callers at the cost of a network hop.
Then draw the picture in one pass, narrating as you go: "On the left, the client sends a request. The arrow goes to the gateway, and inside the gateway sits the limiter, which makes the allow-or-reject decision. From the limiter, one arrow goes to a shared counter store, partitioned into shards keyed by the limit key, so different keys land on different shards. A second arrow comes back from the limiter to the client carrying the decision, and the request only continues to the backend service when the decision is allow."
Now attach the two decisions the interviewer is listening for. On key formation: "I would form the key as the API key plus the endpoint, because a single key across all endpoints would let one noisy route consume the whole quota." On shard choice: "I would shard by a hash of that key so load spreads evenly, and I would watch for one large tenant whose key becomes hot, because that shard becomes the bottleneck while the rest sit idle." Saying the reason for the key shape and the shard function is what turns a diagram into a design.
Explain why a shared counter store is usually needed once you run more than one instance. If each instance counts locally, a client spread across ten instances effectively gets ten times the limit. Keep the diagram small enough to explain in two minutes.
Step 5: Talk About Scale, Consistency and Failure
This is the section that separates strong answers from adequate ones, so slow down here. These are the system design trade offs interviewers listen for, and they are usually what decides the outcome of a rate limiter system design interview. Two of them deserve a worked answer; the rest can stay as brief pointers.
Atomicity, worked out loud
Say it like this: "The increment-and-check has to be one atomic operation. If I read the counter, decide there is a token left, and then write, two concurrent requests can both read the same last token and both proceed. So I would push the check into the store as a single atomic operation rather than doing it in application code."
A likely follow-up: "What if the store does not support that operation?" A reasonable reply: "Then I would either use a small script that the store executes atomically, or accept a lock around the key, and I would say out loud that the lock costs latency and becomes a contention point for hot keys."
Failure mode, worked out loud
Say it like this: "If the counter store is slow or unreachable, I would fail open for read-heavy public endpoints, because blocking all legitimate traffic is worse than briefly exceeding a limit, and I would log and alert on it. For a limit protecting a fragile downstream service, I would flip that and fail closed."
A likely follow-up: "How do clients know you are failing open?" A reasonable reply: "I would surface it in the response headers and in a metric, so callers can see degraded enforcement rather than guessing."
The rest, as pointers
Consistency is a choice: strongly consistent counters give accurate limits at higher latency and lower availability, while eventually consistent counters are cheaper and faster but can briefly over- or under-count. Say which you would accept and why. Replication buys availability at the cost of coordination. Clock skew means wall-clock windows can behave differently across nodes, which is an argument for a store that owns the notion of time rather than trusting each caller.
Step 6: Define the Client Contract
A limiter is only useful if callers can respond to it. Describe the status code you return when a request is rejected, plus two headers: one that tells the client when to retry, and one that reports the remaining quota for that key. That second header is where the remaining-quota requirement from Step 2 actually lands, so say it explicitly rather than leaving it as an abstraction.
Decide whether rejected requests are counted. Counting them is stricter and can punish a client that retries aggressively; not counting them is more forgiving but easier to abuse. Either way, explain the fairness consequence.
Say how you would document limits so API consumers can plan around them, and how you would version or change a limit without breaking existing clients. A limit change that silently breaks a partner integration is a product problem, not just a technical one.
Step 7: Close With Trade-Offs and What You Would Do Differently
Summarise the two or three decisions you would defend and the ones you would revisit. Name the metric you would watch first in production, such as the share of requests being rejected or the added latency at the limiter.
Mention one thing you would simplify if the interviewer pushed for a smaller scope. Then leave a beat for questions. The closing is part of the interview, not an afterthought.
How to Practise This Walkthrough Out Loud
Reading a walkthrough is not the same as performing one. Rehearse the requirements questions until they sound natural rather than recited, because a memorised list is audible.
The drill that pays off most is narrating a single rejected request end to end, in the words you would actually use. It sounds like this: "The client sends a request. The limiter forms the key, checks the counter on the relevant shard, and the counter says the quota is spent, so the decision comes back as reject. The client reads the retry header, waits, and tries again." Then add the second half: "If the counter store had timed out instead, I would have failed open, returned the request, and logged the degraded enforcement." Saying that loop out loud forces you to connect the counting approach, the rate limiter architecture and the client contract in one breath, which is exactly what the interviewer is following.
Run the same structure on a second question, such as a URL shortener, to check that it transfers. The structure is the asset; the rate limiter is just the case you are practising it on. More walkthroughs in this style live on our blog.
If you use a practice tool, treat it as rehearsal for honest answers, not as a source of answers to memorise. The interviewer is scoring your reasoning, and borrowed reasoning tends to fall apart the moment they ask a follow-up. If you want to review how your practice is going, our support page is the place to start.
The takeaway: ask before you draw, name a trade-off every time you make a choice, and leave time to discuss failure. Do that and the rate limiter system design interview becomes a demonstration of how you think rather than a memory test.
Frequently asked questions
How long should I spend on requirements before drawing the rate limiter architecture?
Long enough to answer four questions: who the clients are, what is being limited, whether bursts are allowed, and what happens if the counter store is down. Once you can say the agreed requirements back in one sentence, start drawing.
Should I choose token bucket or sliding window in a rate limiter system design interview?
Either can be right. Token bucket suits limits that allow short bursts while enforcing an average rate. Sliding window counter suits strict per-window fairness with modest memory cost. Pick one, give your reason in a sentence, and say what would change your mind.
Do I need to write code in a system design interview, or is a diagram enough?
Usually a diagram plus clear narration is enough. If the interviewer asks for detail, sketch the shape of the increment-and-check operation rather than full production code, and explain why atomicity matters there.
What should I say if I do not know the exact algorithm the interviewer has in mind?
Say what you do know and reason from the requirements. For example, state the behaviour you need, describe two candidate approaches, and explain which you would try first and why. Interviewers generally reward visible reasoning over a lucky guess.
How do I talk about trade-offs without sounding indecisive?
Use the same pattern as the counting choice: state a choice, give the reason, then say what would change your mind. "I would start with token bucket because it expresses burst and average rate in two parameters; if strict per-window fairness mattered more, I would switch to sliding window counter." That reads as a decision with a condition attached, not as hedging.
Can I reuse the same structure for other system design questions?
Yes. Clarify, state requirements, choose an approach with reasons, sketch, discuss scale and failure, define the client contract, and close with trade-offs. Practising it on a second question such as a URL shortener shows whether the structure transfers.
Rehearse this walkthrough out loud and review your trade-offs.