Devscape blog
All posts

estimationfundamentals

Back-of-the-envelope estimation for system design interviews

The eight numbers worth memorising, the four-step method that turns a vague brief into QPS and terabytes, and a worked example — sized the way an interviewer expects you to size it.

Halfway through a system design interview somebody will ask how big the database needs to be, and the honest answer — "I'd have to measure it" — is the one answer that fails. They are not testing arithmetic. They are testing whether you can tell a design that needs one machine from a design that needs a thousand, because those are different designs and you cannot pick between them by instinct.

The good news is that the whole skill is four steps and about eight numbers, and it is the most learnable part of the entire interview.

Start with the second, not the day

Every estimate in this interview starts by converting a per-day figure into a per-second one, so make that division free.

That single conversion answers most of what gets asked. A million signups a day sounds enormous and is ten writes a second, which is a laptop. A billion events a day sounds similar and is twelve thousand a second, which is a fleet. Being able to say which one you are in, out loud, in five seconds, is most of the value.

The numbers worth memorising

You need eight. Not the famous latency table with twenty rows in it — nobody has ever needed the L1 cache reference time to size a service.

QuantityUse it for
Day ≈ 10^5 secondsper-day → per-second
Year ≈ 3 × 10^7 secondsgrowth and retention
Memory read ≈ 100 nswhy a cache hit is free
SSD random read ≈ 100 µswhy a cold read is not
Round trip inside a datacentre ≈ 0.5 mswhy chatty services are slow
Round trip across the world ≈ 150 mswhy you need a CDN
1 KB × 1 million ≈ 1 GBrows → gigabytes
1 KB × 1 billion ≈ 1 TBrows → terabytes

The last two are the ones candidates most often lack, and they are the ones that turn a row count into a storage bill in one step. Commit those and you can size any table in your head.

Two more that are worth carrying because they end arguments: a single Redis node handles on the order of 100,000 operations a second, and a single Postgres node handles on the order of a few thousand writes a second. When your estimate lands under those, say so — "this fits on one box" is a complete and often correct answer, and volunteering it is how you show you know when not to distribute.

The method

One — get the driving number. Ask for it rather than inventing it. "How many daily active users should I design for?" is a question interviewers are happy to answer, and it anchors everything downstream. If they push it back to you, pick a round number, say it out loud, and move.

Two — turn users into requests. How many times a day does one user do the thing? Then split reads from writes. Read/write ratios are wildly asymmetric in almost every real product, and a design that ignores that is a design that caches nothing.

Three — take it to peak. Average traffic is not what your system has to survive. A product used during working hours does most of a day's volume in about four hours, so peak runs 2× to 10× the average. Say which multiplier you are using and why.

Four — convert to the resource that matters. Requests per second sizes the service tier. Bytes per row times rows per day sizes storage. Bytes per second sizes the network and the bill.

A worked example

Say the brief is a paste service — text in, short link out — and the interviewer gives you 5 million daily active users.

Requests. Assume one action per user per day: 5M requests a day.

5,000,000 ÷ 100,000 s  =  50 requests/second average

Call it 58 with the real 86,400. Peak at 10× — a text-sharing tool is bursty and working-hours-shaped — gives ≈ 580 requests/second at peak. That is one number, and it already tells you the answer: a handful of application servers behind a load balancer. Not a fleet.

Split reads and writes. A paste is written once and read many times; 10% writes is a defensible guess. So 500,000 new pastes a day, ≈ 6 writes/second average, 60 at peak. Sixty writes a second is comfortably inside one Postgres node — say that, because it is the moment you demonstrate you are not going to shard something that does not need sharding.

Storage. Say the average paste is 2.5 KB of text plus metadata.

500,000 × 2.5 KB  =  1.25 GB/day
1.25 GB × 365     ≈  450 GB/year

Under half a terabyte a year. One disk. Now the interesting follow-up is not sharding, it is retention: at three years you are at 1.4 TB and still fine, so the design question is whether pastes ever expire, not how to split them.

Cache. Reads concentrate on recent pastes. If the hot set is the last 30 days, that is 1.25 GB × 30 ≈ 40 GB — one large cache node holds the entire working set, and a 90% hit rate takes the database down to a trickle.

A four-box diagram: 5M daily users to an API sized at 580 requests per second peak, which reads from a 40 GB cache with a 90% hit rate and falls through to a store growing 450 GB a year.
Every number from the estimate, written onto the box it constrains. This is what the arithmetic is for — the design now has sizes on it, and each one is defensible.

Four sums, and the architecture is decided: a small stateless tier, one cache holding the hot window, one database that will not need splitting for years. Notice that the estimate did not just decorate the design — it ruled things out, which is the whole point.

Where candidates lose points

Precision instead of accuracy. "86,400 seconds times 0.7 utilisation" is someone doing sums when they should be doing engineering. Round hard, out loud. Nobody has ever been marked down for saying "call it a hundred thousand".

Skipping peak. Sizing to the average is how a design that looks fine falls over at 9am. Applying a multiplier takes four seconds and is a thing interviewers actively listen for.

Silent arithmetic. If you work it out in your head and announce the answer, you have shown nothing. The reasoning is the artefact being graded — a wrong number reached out loud by sound steps scores better than a right one produced from nowhere.

Practise the conversion, not the table

Memorising latency numbers feels like progress and mostly is not. What actually transfers is the reflex: hear a per-day number, say the per-second number, apply peak, convert to bytes. Do it on things you use. Your team's CI runs how many builds a day? Your API serves how many requests a second at lunchtime?

Then do it under the only condition that matters — with a brief you have not seen before and a clock running.

Now design it yourself

Draw the architecture on a board and have it graded against the things an interviewer pushes on. Free, and no account needed.