
Most lists of system design interview questions are just that: a list. "Design Twitter." "Design a rate limiter." "Design a URL shortener." Useful as a starting point, useless on their own, because the question is not what makes the interview good. What makes it good is knowing which follow-up to ask when the candidate draws a box labeled "cache" and moves on.
This post gives you both halves: a set of questions organized by what each one is actually built to surface, and a transcript comparing a rehearsed answer to a reasoned one so you can hear the difference before you're sitting across from a candidate.
A system design interview is not a knowledge quiz about distributed systems vocabulary. Candidates who have read a few good primers, like the widely used system-design-primer on GitHub, can all recite "add a cache, shard the database, put a queue in front of it." That vocabulary is table stakes, not signal.
The actual thing you are hiring for is judgment under ambiguity: can this person take a vague prompt, ask the questions that narrow it, estimate the numbers that matter, and defend a tradeoff out loud when there is no single correct answer. A system design interview is one of the few formats built specifically to watch that process, because the problem is deliberately underspecified. There is no compiler to tell the candidate they're right.
Picking a random question from a bank gives you a random signal. Picking one for the skill you're trying to see gives you a real assessment. Here are four groups we've seen work, with the reasoning behind each.
Examples: design a URL shortener, design a rate limiter, design a key-value store.
These are the right opener for mid-level candidates because the domain is familiar, so the interview isn't spent explaining the problem. What you're watching for is whether the candidate does the arithmetic before drawing anything: how many writes per second, how big is a record, does that fit in memory on one box or does it need to be partitioned. A candidate who jumps straight to "we'll use Redis and Kafka" without ever writing down a number has skipped the part of the exercise that was actually being scored.
Examples: design a chat application, design a collaborative document editor, design a live notification system.
These questions exist to force an explicit stance on consistency versus availability, because the naive answer ("just replicate everything") breaks the moment you ask what happens when two replicas disagree during a network partition. A strong candidate names the tradeoff directly: "for typing indicators I'll accept eventual consistency and even some loss, for message ordering within a conversation I won't." A weak candidate says "we'll use a distributed database" and hopes the interviewer doesn't ask which one, or why.
Examples: design a search autocomplete feature, design an analytics pipeline that ingests millions of events per day, design a news feed ranking system.
The interesting decision here is almost never the transport layer. It's the data model and the read/write asymmetry: autocomplete is read-heavy and can tolerate a slightly stale index; an analytics pipeline is write-heavy and can tolerate slow, batched reads. Candidates who default to the same architecture regardless of which system they're asked about haven't actually understood either one.
Examples: design a payment processing system, design a ride-matching system, design a distributed lock service.
These are the hardest questions in the set and worth reserving for senior and staff-level candidates, because a wrong answer here has real consequences in production, not just a slow page load. The interview should specifically probe idempotency, retries, and what happens on partial failure: if the payment call succeeds but the confirmation write times out, what actually happens to the customer's money. A candidate who has operated one of these systems will bring up idempotency keys unprompted. One who hasn't will need to be walked there, which is itself useful information about their level.
Abstract advice about "look for tradeoffs" is hard to apply live. Here's what the difference actually sounds like, using "design a rate limiter" as the prompt.
Weak answer: "I'd use a token bucket algorithm. Each user gets a bucket in Redis, and we check it on every request. If we need it to scale, we'd shard Redis." The candidate has named a real algorithm, which sounds good, but never explained why token bucket over fixed window, never mentioned what happens when the Redis call itself is slow or unavailable, and treated "shard Redis" as a complete answer to a question nobody asked yet.
Strong answer: "First, what are we rate limiting: per user, per IP, per API key? That changes the key space a lot. Let's say per API key, and say we're doing 50,000 requests a second at peak. I'd lean toward a sliding window counter over a strict token bucket because it smooths bursts better without needing a background refill process. The limiter has to be fast, on the request hot path, so I want it in-memory at the edge with async writes to a shared store for the count, not a synchronous call on every request. If the shared store is briefly unavailable, I'd rather fail open for a few seconds than take down the whole API to protect it from itself. That's a real tradeoff between correctness and availability, and I'd want the team to sign off on which side we land on."
The second answer isn't longer because the candidate rambled. It's longer because they asked a clarifying question, attached a number to the design, compared two real alternatives instead of naming one, and stated an explicit tradeoff instead of hiding it. That's the entire skill the question exists to surface.
Two interviewers can watch the same session and walk away with different verdicts unless the scoring criteria are written down in advance. We cover the general version of this in how to write a technical interview rubric, but for a system design conversation specifically, score against behaviors, not vocabulary:
A shared scorecard like the one in the practical interview scorecard keeps this consistent across a panel, which matters more for system design than almost any other interview format, because the lack of a single correct answer is exactly what makes two interviewers drift apart without one.
A pure discussion format is legitimate for architecture-level questions where the candidate is mostly reasoning about tradeoffs that would take days to build. But for the piece of the design that actually carries the risk, like the rate limiter's edge case or the retry logic in a payment flow, talking about it and building it surface different things. We've watched candidates describe a correct retry strategy fluently and then, handed a real workspace with a flaky downstream service, write a retry loop with no backoff and no idempotency check.
That's why some of our customers' system design interviews end with a short build step: take the piece you just designed on the whiteboard, implement it against a small live service in an EasyEnv workspace, and run it against a script that fires concurrent or duplicate requests. It's not a replacement for the design conversation, it's a check on it. The design tells you what the candidate thinks the right answer is. The fifteen minutes of implementation tells you whether they actually believe it enough to build it that way. If you want the debugging-focused version of this same idea, see how to assess debugging skill.
Pick your question for the skill you're trying to see, not from the top of a list. Write down what a strong answer sounds like before the candidate walks in, using the clarify, quantify, compare, commit pattern above. And if the design includes a piece where a wrong assumption would actually break something in production, consider asking the candidate to build just that piece instead of only describing it.
What would change in your last five system design interviews if you scored the questions asked before the diagram was drawn?
Run live coding sessions and take-home challenges in real production environments. Watch sessions back, score consistently, and hire with confidence.
More posts you might like
LeetCode's hiring product is a legitimate, well-built screen for algorithm-heavy roles. The trouble starts when it gets used to screen roles it was never built for. Here is how to tell which situation you are in, and what to look for in a real-environment alternative.
Validating AI-generated code is a different skill from reviewing a colleague's pull request, and treating it the same way is why bugs get through. Here is a risk-based way to decide how much scrutiny a given piece of generated code actually needs, plus the five-minute floor you should never skip.
Read moreThe two terms get used as synonyms in job ads and training decks, but they measure different things. Here is the actual distinction, why it matters for hiring and training budgets, and how to tell which one you are looking at.
Read more