Back-of-the-envelope estimation
Size a system in two minutes without a calculator: turn daily users into QPS, storage and bandwidth, then defend the number that picks the architecture.
Estimation is how a design stops being an opinion. Two candidates draw the same three boxes and a queue; the one who shows that the write path is 12 QPS and the read path is 1,000 QPS has turned "we should shard" into a claim that can be checked and, if wrong, corrected. The arithmetic below runs in two minutes on paper, and its constants are worth memorising because you will not have a calculator.
The pipeline
Every capacity estimate walks the same chain, from users to hardware.
Two inputs are guesses: daily active users, and actions per user per day. Everything downstream is multiplication. State both out loud — they are the only numbers an interviewer can disagree with, and a corrected input costs ten seconds of rework, not a wrong architecture. Fix them against the functional requirements from requirements gathering; estimation is step two of the four-step framework in the roadmap, and it is worthless before step one has settled what the system does.
Constants to memorise
| Constant | Value | What it decides |
|---|---|---|
| Seconds in a day | 86,400, round to 100,000 | Requests-per-day to QPS |
| 1 million requests/day | ~12 QPS average | The everyday traffic unit |
| 1 billion requests/day | ~12,000 QPS average | Whether you are actually at web scale |
| Peak multiplier | 2–5x average | What you provision, not what you use |
| 1 KB x 1 million | 1 GB | Metadata and row counts |
| 1 KB x 1 billion | 1 TB | Message and event logs |
| Commodity Postgres box | ~5,000 simple QPS | Shard or not |
| Datacenter round trip | 0.5 ms | Cost of an extra service hop |
| SSD random read | 100 µs | Cost of a cache miss |
| Memory reference | 100 ns | Why cache beats disk by 1,000x |
The 12 QPS figure earns its keep: 86,400 seconds is close enough to 100,000 that a million a day is roughly 10 per second, the true answer is 11.6, and 12 is easy to multiply and slightly conservative.
Round to one significant figure
Estimates pick between architectures, and the gap between architectures is a factor of ten, not 1.4. One box or a fleet. Neither flips because you wrote 217 instead of 200.
So round every intermediate to one significant figure and prefer powers of ten: 86,400 becomes 100,000, 1.5 MB per photo becomes 2 MB, 43 servers become 50. Round in the direction that makes the system bigger, so errors accumulate into headroom, not an outage. If a decision flips when you round — 4,800 QPS against a 5,000 QPS box — that is the interesting finding: "this is inside the noise, so I would design for the shard."
Worked example: photo sharing
Assume 1 million DAU, each viewing 20 photos a day, with 20% of users uploading one photo.
Reads: 1M DAU x 20 views = 20M reads/day
20M/day x 12 QPS per M = 240 QPS average
cross-check: 20M / 86,400 s = 230 QPS
peak at 4x = ~1,000 QPS
Writes: 1M DAU x 0.2 uploads = 200k uploads/day
0.2M/day x 12 = ~2.4 QPS average
peak at 4x = ~10 QPS
Storage: 200k uploads x 2 MB = 400 GB/day
400 GB x 365 = ~150 TB/year of blobs
Metadata: 1 KB x 200k rows = 200 MB/day = ~70 GB/year
Egress: 240 QPS x 200 KB = ~50 MB/s average
peak 1,000 QPS x 200 KB = 200 MB/s = ~1.6 Gbps
The consequence is the point. 230 QPS average means a single primary is fine; do not shard — that is 20x headroom against the 5,000 QPS box, and 70 GB of metadata a year fits one disk for a decade. The only number forcing a design change is 1.6 Gbps of image egress, and images are static bytes, so a CDN absorbs it. A candidate who shards this database has read the word "photos" and stopped reading the numbers.
Worked example: chat
Assume 50 million DAU, each sending 40 messages a day in one-to-one conversations.
Writes: 50M x 40 = 2B messages/day
2B/day x 12,000 per B = ~24,000 QPS average
peak at 3x = ~72,000 QPS, round to 100,000
Storage: 2B messages x 1 KB = 2 TB/day
2 TB x 365 = ~700 TB/year
x3 replication = ~2 PB/year
Sockets: 10% of DAU online = 5M concurrent connections
at 50k per box = ~100 connection servers
24,000 QPS of writes against a 5,000 QPS box is at least five shards before replication, so partitioning by conversation ID is a first-class decision, not a later optimisation — see database scaling for how that key constrains queries. The 5 million connections are a separate tier, because WebSocket servers are sized by open sockets and memory, not QPS. And 2 PB/year forces a retention decision early: hot storage for 30 days, cold object storage after.
Little's Law closes the loop for pool sizing: concurrency equals arrival rate times latency. 24,000 QPS at 20 ms per write is 480 requests in flight; if the datastore degrades to 200 ms that becomes 4,800 against a pool holding a few hundred, and the tier fails on saturation rather than throughput — see concurrency.
The estimate is a falsifiable claim, not a measurement
None of these numbers is accurate. 50 million DAU is a guess, 40 messages a day is a guess, and 1 KB per message ignores metadata. That is fine: the estimate says if these inputs hold, this architecture is right, and here is the input whose change would break it — testable in the room, correctable in six months.
The failure mode is not imprecision. An estimate you cannot defend is worse than no estimate, because it launders a guess into a specification nobody re-examines. If you cannot say where a number came from and which decision it drives, delete it and say "I don't know yet, and here is how I would measure it."
In an interview
What is tested is not arithmetic but whether your numbers change your design. The interviewer watches for one behaviour: you compute a figure, and the next sentence is a consequence for the architecture.
Say the assumptions first and invite correction: "I'll assume 10 million DAU and 20 actions each — tell me if that's off by an order of magnitude." Round out loud: "call it 100,000 seconds in a day." Then land it: "that's 2,000 QPS peak, which one primary and a read replica handle, so I'm not sharding, and a 10x jump in writes is what would change my mind."
The mistake that loses points is doing the arithmetic and then abandoning it — five minutes of confident multiplication followed by a design identical to the one you would have drawn at 100x the traffic. The runner-up is precision theatre: carrying 86,400 through four multiplications to produce 217.44 QPS. Both say estimation was learned as a ritual, not a decision procedure.
Check yourself
A URL shortener serves 100 million redirects a day and creates 1 million new links a day. Do you shard the database?
No. 100M/day is about 1,200 QPS average and 3,600 QPS at 3x peak, under the ~5,000 QPS single-box threshold, and writes are 1M/day, about 12 QPS. Redirects are a pure key lookup with a high cache hit rate, so the origin sees a fraction of 1,200 QPS. Add a cache before you add a shard.
A logging service ingests 10,000 events per second, 500 bytes each. Can you keep a year of it on one machine?
10,000 x 500 B = 5 MB/s, which is 432 GB/day and about 150 TB/year. Not one machine. But 30 days is roughly 13 TB, which does fit one large disk, so the real decision is a retention window plus object storage for the tail, not a distributed database.
Your service handles 500 QPS and calls a dependency with 200 ms p99 latency. How many connections must the pool hold, and what happens at 400 ms?
Little's Law: 500 x 0.2 s = 100 concurrent requests in flight, so the pool needs 100 connections plus headroom. At 400 ms it doubles to 200; a pool of 100 then queues, latency climbs, and the tier fails from saturation while the dependency is merely slow rather than down. Size pools from latency, and set a timeout shorter than the client's patience.