Why Estimate at All
the 5-minute sanity checkEstimation is how you find the bottleneck before you draw around it. A number tells you whether the data fits in memory or needs a hundred machines, whether reads or writes dominate, whether the payload is the story or the request count is. Skip it and you're designing blind, and the interviewer knows it.
The goal is not precision. It's the right order of magnitude, fast, so the rest of your design rests on something real. "It should scale" is not an answer. "That's 4 GB/s of egress, so this is a CDN problem, not a database problem" is.
Numbers to Memorize
powers ยท latency ยท throughput ยท timeYou can't derive these in the room, so carry them in. Four small tables cover almost every question. Round everything; the point is the ratio between numbers, not the numbers themselves.
| Power | โ Value | Name |
|---|---|---|
| 2^10 | 1 thousand | Kilobyte (KB) |
| 2^20 | 1 million | Megabyte (MB) |
| 2^30 | 1 billion | Gigabyte (GB) |
| 2^40 | 1 trillion | Terabyte (TB) |
| 2^50 | 1 quadrillion | Petabyte (PB) |
| Operation | Time | What it tells you |
|---|---|---|
| L1 cache reference | 1 ns | The floor. Everything is measured against this. |
| Main memory reference | 100 ns | ~100ร slower than L1, still effectively free. |
| Read 1 MB from memory | 250 ยตs | RAM is fast but not infinite; big scans still cost. |
| SSD random read | 100 ยตs | ~1000ร slower than memory. Cache to avoid it. |
| Read 1 MB from SSD | 1 ms | ~4ร the memory read. SSD is closer to RAM than to disk. |
| Datacenter round trip | 0.5 ms | A network hop inside one region is cheap. |
| Disk seek (rotational) | 10 ms | ~100,000ร a memory reference. Random disk I/O is death. |
| Read 1 MB from disk | 20 ms | Sequential disk is tolerable; random is not. |
| Round trip US โ Europe | 150 ms | Cross-region on the request path is poison. |
| Resource | Rough ceiling |
|---|---|
| App server (simple req) | ~10K QPS |
| SSD | ~100K IOPS, ~1 GB/s |
| DB primary (writes) | ~a few K/s |
| Redis / cache node | ~100K ops/s |
| 1 Gbps link | ~125 MB/s |
| 10 Gbps link | ~1.25 GB/s |
| Interval | Seconds |
|---|---|
| Per day | 86,400 โ 100K |
| Per month | ~2.5 million |
| Per year | ~30 million |
Rounding a day to 105 seconds is the single most useful move in this whole page. It turns "requests per day รท seconds per day" into a clean shift of the decimal point.
Estimating QPS
DAU โ average โ peakThe derivation is always the same four steps: start from daily active users, multiply by how many times each one hits the feature per day, divide by seconds per day for the average, then multiply by a peak factor because traffic is never flat.
โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
โ 100M โ ร โ 5 requests โ = โ 500M reqs โ รท โ 100K sec โ = โ 5K QPS โ
โ DAU โ โ per user/day โ โ per day โ โ per day โ โ average โ
โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโฌโโโโโโ
โ
peak factor ร2 to ร5 (here ร3) โ
โผ
โโโโโโโโโโโโ
โ 15K QPS โ
โ peak โ
โโโโโโโโโโโโ
- DAU: 100M users open the app on a given day.
- Actions per user: each refreshes the feed ~5 times โ 500M feed reads/day.
- Average QPS: 500M รท 100K seconds = 5,000 QPS.
- Peak QPS: traffic clusters around evenings and events, so ร3 โ 15,000 QPS.
- Sanity check: one app server handles ~10K simple QPS, so this is a handful of machines plus headroom, not a heroic system. That feels right for a read of a cached feed.
Estimating Storage
size ร rate ร retention ร replicasStorage is a multiplication: how big each object is, times how many you write per day, times how long you keep them, times how many copies you hold. The trap is treating all data as one number. Split it: small metadata scales differently from large payloads, and one of them usually dwarfs the other.
writes/day object size retention replication
200M tweets ร 500 bytes ร 365 days ร 3 copies
โ โ โ โ
โโโโโ 100 GB/day โ โ โ
โโโโโโโโโโโโ 36 TB/year โโโ โ
โโโโโโโโโโโโโ ~110 TB stored โ
Text and metadata. 100M users post ~2 tweets/day โ 200M tweets/day. Text plus IDs, timestamps and user reference is ~500 bytes.
- Per day: 200M ร 500 B = 100 GB/day.
- Per year: 100 GB ร 365 โ 36 TB/year.
- With 3ร replication (Replication): โ 110 TB. Fits on a modest cluster.
Media. Say 10% of tweets carry a 200 KB image โ 20M images/day.
- Per day: 20M ร 200 KB = 4 TB/day.
- Per year: โ 1.5 PB/year, and โ 4.4 PB replicated.
The image bytes are 40ร the text bytes. This design is a blob-storage-and-CDN problem wearing a database costume. Say that out loud, then keep media out of the database entirely (Specialized Stores).
Bandwidth & Memory
ingress ยท egress ยท cache sizingBandwidth falls straight out of the storage math: a per-day byte total divided by seconds per day is a byte rate. Split it two ways. Ingress is what you take in (roughly your write volume). Egress is what you serve out, and on a read-heavy system it's larger by the read/write ratio.
| Flow | Rate | Consequence |
|---|---|---|
| Text ingress | 1 MB/s | 100 GB/day รท 100K s. Trivial. |
| Media ingress | 40 MB/s | 4 TB/day รท 100K s. One fat link handles it. |
| Media egress (100:1 reads) | 4 GB/s | 40 MB/s ร 100. No origin serves this; you need a CDN. |
You rarely cache everything. Roughly 20% of the data serves 80% of the reads: recent tweets, popular items, active users. Size the cache to the hot set, not the corpus.
- Daily text written: ~100 GB. The hot working set that reads actually touch is a fraction of that.
- Cache the hot 20% โ 20 GB, which fits in the RAM of a single cache node with room to spare.
- Lesson: for small-payload, read-heavy systems, the working set fits in memory. That's the same insight that makes a URL shortener cheap, and it's why caching is the highest-leverage move you have.
Rounding Discipline
round hard, keep units- Round to one significant figure. 86,400 becomes 100K, 365 becomes 400 (or just leave the year as ~30M seconds). You're finding the order of magnitude, not balancing a ledger.
- Keep units on every line. Bytes/day, GB, QPS, MB/s. Half of all estimation errors are a lost factor of 1000 from dropping a unit. The unit is the error check.
- Carry powers of ten, not commas. 500M is 5 ร 108; 100K seconds is 105. Dividing is subtracting exponents: 108 รท 105 = 103 = a few thousand QPS.
- Sanity-check against a known ceiling. 15K peak QPS against ~10K per server means a few machines. 4 GB/s egress against a 1.25 GB/s link means it cannot be one origin. The check catches the dropped-1000 error instantly.
- Stop when the number decides the design. Once you know it's "TB not PB" or "CDN not database," the estimate has done its job. More digits are theater.
Quick Reference
the numbers on one card| Quantity | Value | Note |
|---|---|---|
| Seconds/day | ~100K (10^5) | The workhorse. Round 86,400 up. |
| Seconds/year | ~30M | For retention math. |
| KB / MB / GB / TB / PB | 10^3 โฆ 10^15 | Each step is ร1000. |
| Memory reference | 100 ns | Effectively free. |
| SSD random read | 100 ยตs | ~1000ร memory. |
| Disk seek | 10 ms | Avoid random disk I/O. |
| Same-region round trip | 0.5 ms | Cheap. |
| Cross-region round trip | ~150 ms | Never sync on the request path. |
| App server | ~10K QPS | Divide peak QPS by this for fleet size. |
| 1 / 10 Gbps link | 125 / 1250 MB/s | Check egress against this. |
| Target | Formula | Then |
|---|---|---|
| Average QPS | DAU ร req/user รท 100K | ร 2โ5 for peak |
| Fleet size | peak QPS รท ~10K | + headroom & redundancy |
| Storage/year | obj size ร writes/day ร 365 | ร ~3 for replicas |
| Ingress | bytes written/day รท 100K | โ write bandwidth |
| Egress | ingress ร read/write ratio | > link capacity โ CDN |
| Cache size | hot-set bytes (~20% of daily) | fit in RAM if you can |