The method & napkin math
A design interview is not a trivia quiz about Kafka and Cassandra. It is a test of whether you can take a one-sentence prompt and drive it to a design you can defend under pushback. The single highest-leverage skill is arithmetic done out loud: the numbers decide the architecture, not the other way round.
The most common failure mode at the senior level is not ignorance of any particular technology — it is starting with technologies. A candidate hears "design a URL shortener" and immediately says "I'll put it behind a load balancer, shard the writes across Cassandra, and front it with Redis." That answer is unfalsifiable: it cannot be wrong because no requirement was ever stated, and it cannot be right for the same reason. The interviewer learns nothing except that you have memorised a stack. What they want to see is the inverse: you extract requirements, you turn them into numbers, and the numbers select the components. If your estimate says the whole thing fits on one box, the senior answer is one box — and saying so confidently is a stronger signal than reaching for a distributed database you do not need.
The repeatable seven-step script
Run the same loop every time. It costs you nothing to memorise and it stops you from freezing. The order matters: each step constrains the next, and skipping ahead to architecture before you have numbers is the cardinal sin.
Budget roughly 5 minutes on steps 1–2, then most of the hour on 5–6. Step 2 is the hinge: it is where you earn the right to draw boxes. A request for "design Twitter" is a request to size the fan-out problem; a request for "design a parking-lot reservation system" is almost never a scale problem at all, and recognising that is itself the point.
Requirements before architecture, always
Drive the requirements with sharp, closed questions — open-ended "what should it do?" wastes your minute. Ask: How many users? What is the read-to-write ratio? What is the p99 latency target? Do reads have to see the latest write, or is stale-by-seconds fine? How durable — can we lose the last second of writes on a crash? Each answer is a constraint that eliminates designs. "Stale-by-seconds is fine" buys you caching and async replication (covered in 06 and 08); "must read your own writes" forbids naive read replicas and pushes you toward the consistency mechanisms in 09. State these out loud so the interviewer can correct your assumptions early, before you have built on top of a wrong one.
Latency numbers every engineer should know
The reason "where does the data live?" is the first question in every deep dive is that the storage tier sets the latency floor before a single line of application code runs. The hierarchy spans nine orders of magnitude, and each tier is roughly 10–100× slower than the one above it. You cannot optimise your way across a tier boundary; you can only avoid crossing it. Memorise the shape, not the digits.
| Operation | Latency (order of magnitude) | Relative to L1 |
|---|---|---|
| L1 cache reference | ~0.5 ns | 1× |
| Branch mispredict | ~5 ns | 10× |
| L2 cache reference | ~7 ns | 14× |
| Mutex lock / unlock | ~25 ns | 50× |
| Main-memory reference | ~100 ns | 200× |
| Compress 1 KB | ~3 µs | 6,000× |
| Read 1 MB sequentially from memory | ~3 µs | 6,000× |
| SSD random read | ~16 µs | 30,000× |
| Read 1 MB from SSD | ~50–150 µs | ~200,000× |
| Round trip within a datacenter | ~0.5 ms | ~1,000,000× |
| Disk seek (spinning) | ~2–10 ms | ~10,000,000× |
| Read 1 MB from spinning disk | ~1–5 ms | ~5,000,000× |
| Packet CA → Netherlands → CA | ~150 ms | ~300,000,000× |
Three load-bearing consequences fall out of this table. First, a cross-region round trip (~150 ms) is dominated by the speed of light, not by software — no amount of tuning fixes a chatty protocol that makes ten serial transatlantic hops; you batch or you move the data closer. Second, a same-datacenter RPC (~0.5 ms) is about 5,000× a main-memory read, so a request that touches memory a thousand times is still cheaper than one that makes a single extra network call: collapse network hops first, micro-optimise code last. Third, an SSD random read (~16 µs) is ~150× faster than a disk seek (~5 ms), which is why "is it on SSD?" is often the difference between a 10 ms and a 1 s page load. We turn these constants into throughput limits in 02.
Powers of two and the per-second trick
Estimation runs on two cheat sheets you should be able to recite. The first maps binary exponents to the SI-ish names we throw around; the second collapses "per day / month / year" into "per second" so QPS falls out instantly.
| Power | Approx value | Bytes name | So 1 unit of that many bytes is… |
|---|---|---|---|
| 2¹⁰ | ≈ 1 thousand (1K) | KB | a short text record |
| 2²⁰ | ≈ 1 million (1M) | MB | a small image / 1000 text rows |
| 2³⁰ | ≈ 1 billion (1B) | GB | fits in RAM on one box |
| 2⁴⁰ | ≈ 1 trillion | TB | one large disk |
| 2⁵⁰ | ≈ 10¹⁵ | PB | a fleet; now you shard |
The time shortcuts are the other half. Commit these three:
1 day ≈ 86,400 s ≈ 10⁵ s · 1 month ≈ 2.6 × 10⁶ s · 1 year ≈ 3.15 × 10⁷ s
The practical move: to convert "X per day" into per-second, divide by 10⁵ (close enough to 86,400). So 1 million events/day ≈ 10 events/s; 1 billion/day ≈ 10⁴/s. Then multiply by a peak-to-average factor — for human-driven traffic, peak is commonly 2×–10× the daily mean because activity clusters in waking hours and around events. Carrying one significant figure is plenty; the interviewer cares that 3,000/s and 30/s imply different architectures, not whether it is 2,847 or 3,112.
Prompt: 1 million daily active users (DAU). Each user does 50 reads and 5 writes per day. Each record ≈ 1 KB. Retain 1 year.
- Read QPS (avg): 1M × 50 = 50M reads/day. 50M / 10⁵ ≈ 500/s (precisely 50M / 86,400 ≈ 580/s).
- Read QPS (peak): assume peak ≈ 5× average ⇒ ≈ 3,000/s.
- Write QPS (avg): 1M × 5 = 5M writes/day. 5M / 10⁵ ≈ 50/s (≈ 58/s precise), peak ≈ 250/s.
- Storage/day: 5M writes × 1 KB ≈ 5 GB/day.
- Storage/year: 5 GB × 365 ≈ 1.8 TB.
- Read bandwidth (peak): 3,000/s × 1 KB ≈ 3 MB/s — trivial; a single NIC does 100×+ that.
Verdict: 3,000 read/s and 250 write/s are well within a single modern relational primary (which handles thousands of writes/s on SSD). 1.8 TB fits one disk with headroom. So the defensible answer is: one primary + one read replica + a cache in front for the read-heavy load — no sharding, no distributed database. Reaching for Cassandra here would be a red flag, not a flex. The senior move is naming the threshold at which that changes: when storage approaches a few TB-to-PB, or write QPS approaches the low thousands, then you partition (see 07).
Reading the verdict from the numbers
Estimation is only useful if it terminates in a decision. The ladder below is the mapping from numbers to topology. It is approximate by design — the goal is to land on the right order of magnitude of complexity, and to say out loud which number triggered which choice.
| Signal | Rough threshold | Implication |
|---|---|---|
| Peak read QPS | < ~5k | One primary + cache absorbs it |
| Peak read QPS | ~5k–50k | Add read replicas / scale cache tier (05) |
| Peak write QPS | > ~5k–10k | Single primary strains; partition writes (07) |
| Total storage | > a few TB | Exceeds one box; shard or use distributed store |
| Working set | fits in RAM (≤ ~100s GB) | Cache it; otherwise expect disk-bound reads |
Under-provisioning loses you the offer just as fast as over-engineering. If you wave away a 200k write/s firehose with "a Postgres primary is fine," you have shown you can't read your own arithmetic. The discipline is symmetric: let the number decide. Quote the threshold, compare your estimate to it, and pick the simplest topology that clears it with a safety margin (aim for ~2–3× headroom over peak, since peak estimates are themselves rough).
A back-of-envelope estimator
Drive the inputs below and watch the verdict move. Every KPI is the exact arithmetic from the worked example above; the hint shows the formula so you can reproduce it on a whiteboard.
Interview prompts you should be ready for
- "Where do you start when I say 'design X'?" (With requirements and estimates, not components. I clarify functional + non-functional needs and SLOs, then size QPS/storage/bandwidth — those numbers select the architecture; opening with a tech stack means I'd be guessing.)
- "How do you turn '100 million requests per day' into a QPS number in your head?" (Divide by ~10⁵ since a day is ~86,400 s; that gives ~1,000/s average. Then multiply by a peak factor of 2–10× for human traffic, so ~2k–10k/s peak. One significant figure is enough to pick a topology.)
- "How much slower is a cross-region call than a memory read, and why does it matter?" (About 10⁶× — ~150 ms vs ~100 ns — and it's bounded by the speed of light, so it's not optimisable in software. It means I batch or replicate data into the region rather than make synchronous cross-region calls on the hot path.)
- "At what scale would you stop using a single relational database?" (When total storage approaches a few TB beyond what one box holds, or sustained write QPS reaches the low thousands and a single primary can't keep up. Below that, a primary + read replicas + cache is simpler and more reliable than a distributed store.)
- "You estimated 3,000 read/s. Defend not sharding." (3k/s × 1 KB is ~3 MB/s of bandwidth and well under a single primary's read ceiling, especially fronted by a cache that absorbs the hot keys. Sharding adds cross-shard query and rebalancing complexity with no benefit at this load — premature.)
- "Your peak estimate is probably wrong. How do you protect the design?" (I treat the peak number as approximate and size for ~2–3× headroom over it, and I lean on elastic, stateless tiers that scale horizontally so I can absorb being off by an order of magnitude without a redesign.)
- "When is back-of-envelope math good enough vs. when do you need a real benchmark?" (Estimates are for choosing a topology — they only need the right order of magnitude. Once the design is fixed, I benchmark the specific bottleneck — e.g. write throughput on the chosen DB with realistic record sizes — before committing capacity.)
- "What's the most common mistake you see in these interviews?" (Jumping to 'Kafka + Cassandra + Redis' before stating a single requirement. It's unfalsifiable and signals memorisation. The fix is to let the arithmetic justify every box, including justifying a single box when that's what the numbers say.)
Run the seven-step script every time and never skip from prompt to architecture without numbers in between. Estimation is just two reflexes — divide daily counts by 10⁵ for QPS, and know that each storage tier is 10–100× the one above — applied with one significant figure. The numbers pick the components: when they say "one replicated DB and a cache," say that with confidence, because recognising when distributed machinery is premature is the clearest senior signal you can send. Next, 02 · latency, throughput & queueing turns these constants into hard throughput limits.