📒 problems 📖 glossary
Mock interview
46:30
ready
of 46:30
Lesson 68 · Modern signals

Numbers every engineer should know cold

📖 Walk me through it — plain English

This lesson is about back-of-the-envelope estimation — doing rough math in your head to get an answer that's in the right ballpark. The name comes from the idea that the math is so quick and small you could scribble it on the back of an envelope. In a system design interview (where they ask you to sketch how you'd build something like Twitter or a chat app), nobody expects an exact number. They want to see that you can quickly reason about scale: roughly how much data, how many requests per second, how much storage. The point isn't the number itself — it's that the number tells you what kind of system you have to build. If your math says "6 terabytes a day," that instantly tells you a single database won't cut it and you need to split the data across many machines.

A couple of bits of jargon up front. DAU means "daily active users" — how many distinct people use the app in a day. (You'll also hear MAU, monthly active users; DAU is usually a fraction of MAU, often roughly a quarter to a half.) QPS means "queries per second" — how many requests the system handles each second; some companies say RPS (requests per second) for the same idea. A byte is one character of storage (the letter "A" is one byte); a kilobyte (KB) is ~1,000 bytes, a megabyte (MB) ~1 million, a gigabyte (GB) ~1 billion, a terabyte (TB) ~1 trillion, and a petabyte (PB) ~1,000 TB. Each step up is ~1,000× the one before it — that "×1000 per rung" ladder is worth burning into memory, because mixing up two rungs is how you end up off by a factor of a million. Latency is how long one operation takes; ns is a nanosecond (a billionth of a second), µs a microsecond (a millionth), ms a millisecond (a thousandth). Same ladder, ×1000 per rung: 1,000 ns = 1 µs, 1,000 µs = 1 ms, 1,000 ms = 1 second.

Here's an analogy. Imagine someone asks "how many gallons of water does your whole town use in a day?" You don't measure it — you decompose it: roughly 10,000 households, each uses maybe 100 gallons a day, so ~1 million gallons. You broke one impossible question into three easy guesses and multiplied. That's exactly the move here. Total = users × actions-per-user × size-per-action. Each piece is something you can guess reasonably, even if the final total felt unknowable. The magic is that errors in the pieces tend to partly cancel out — if you guess one factor a bit high and another a bit low, the product stays close. That's why a chain of rough guesses still lands you in the right ballpark.

Let's walk the lesson's Twitter example slowly, one factor at a time:

  • Users: 200M daily active users. Round it to 2 × 10⁸ (that's "2 followed by 8 zeros"). Carrying clean powers of ten makes the multiplication painless. Scientific notation just means writing a number as a small digit times a power of ten: 200,000,000 = 2 × 10⁸ because there are 8 zeros after the 2.
  • Actions: assume each user writes ~100 tweets/day. Multiply: 2 × 10⁸ users × 10² tweets = 2 × 10¹⁰ tweets/day (20 billion). When you multiply powers of ten you just add the exponents: 8 + 2 = 10. (That rule — multiply the front digits, add the exponents — is the single most useful trick in this whole lesson.)
  • Size: assume each stored tweet record is ~300 bytes (the text plus metadata like timestamps and IDs). 2 × 10¹⁰ × 300 ≈ 6 × 10¹² bytes/day = 6 TB/day. Here 10¹² is the "trillion" rung, which is a terabyte — so 6 × 10¹² bytes reads directly as 6 TB.
  • Scale up: 6 TB/day × 365 days ≈ 2,000 TB ≈ 2 PB/year. (6 × 365 ≈ 2,190, which we round to 2,000; and 2,000 TB is 2 PB because 1,000 TB = 1 PB — one more rung up the ladder.)

That 2 PB/year is the payoff. No single hard drive holds that, so the answer writes itself: you need partitioning (splitting data across many machines, also called sharding) and tiered storage (keep recent tweets on fast storage, archive old ones on cheap storage). The estimate handed you the architecture.

The four habits in the cards below are how you keep this fast and credible. Decompose, don't guess — break the whole into users × actions × size. Round aggressively — use 2 × 10⁸, not 200,000,000; chasing exact digits wastes time and the rough answer is just as useful. State your assumptions out loud — say "I'm assuming ~300 bytes per tweet"; this lets the interviewer correct your starting point and shows your reasoning is transparent. Sanity-check the result — if a tiny chat app comes out to 100 PB/day, you slipped a factor of 1,000 somewhere, so go re-derive it. Why does any of this work? Because at the scale of real systems, being within 10× of the truth is plenty to make the right design call, and rough powers-of-ten math gets you there in 30 seconds instead of 30 minutes.

System design rounds reward "let me ballpark that." 30 seconds of math separates a credible answer from hand-waving. Memorize the numbers; learn the moves.

The two moves underneath every estimate

Strip away the topic and every back-of-envelope problem is the same two steps. First, decompose: write the answer as a product of factors you can each guess to within a small multiple — almost always some flavor of quantity × rate × size. Second, multiply in scientific notation: turn each factor into a front digit times a power of ten, multiply the front digits normally, and add the exponents. The reason exponents add is just counting zeros — 10³ (three zeros) times 10⁴ (four zeros) is 10⁷ (seven zeros), because you've lined up seven zeros total. Get comfortable doing arithmetic on the exponents alone and the actual numbers stop being scary.

A QPS estimate uses the same machinery, you just divide by time. To turn a per-day count into a per-second rate, divide by the seconds in a day, which is ~10⁵ (precisely 86,400, but 10⁵ is close enough and far easier). So a system doing 2 × 10¹⁰ writes/day is doing 2 × 10¹⁰ ÷ 10⁵ = 2 × 10⁵ = 200,000 writes/second on average. When you divide powers of ten you subtract exponents: 10 − 5 = 5. Remember this is the average — real traffic peaks above average, so multiply by a peak factor (commonly ~2× to 10×) before sizing for the worst case. A system that averages 200K QPS might need to survive 1M QPS at its busiest minute.

Latency numbers
  • L1 cache ~1 ns · L2 ~4 ns · RAM ~100 ns
  • SSD random read ~100 µs · network within DC ~500 µs
  • Disk seek ~10 ms · cross-continent network ~150 ms
  • Rule of thumb: memory beats disk by 100×, network beats disk by 10×, sequential beats random by 100×.

Why memorize these? Because they decide where data should live. If RAM is ~100 ns and a disk seek is ~10 ms, that's a 100,000× gap (10⁷ ns ÷ 10² ns = 10⁵) — which is exactly why hot data goes in a cache and why a single uncached disk read can dominate a request's whole latency budget. The same numbers explain why one cross-continent round trip (~150 ms) can be slower than thousands of in-datacenter calls (~500 µs each): geography, not CPU, is often the bottleneck. When you reason about a design, walk the request through this table and add up where the milliseconds go.

Powers of 2 / 10
  • 2¹⁰ ≈ 10³ (1 KB · 1 thousand) · 2²⁰ ≈ 10⁶ (1 MB · 1 million) · 2³⁰ ≈ 10⁹ (1 GB · 1 billion) · 2⁴⁰ ≈ 10¹² (1 TB · 1 trillion)
  • Seconds in a day: 86,400 ≈ 10⁵. In a year: ~3 × 10⁷.
  • 1M QPS × 100 bytes = 100 MB/s. 100 GB/day = ~1 MB/s avg.

The first line is the bridge between the two number systems. Computers count in powers of two (memory comes in 2ⁿ chunks), but humans estimate in powers of ten. The happy accident is that 2¹⁰ = 1,024 ≈ 1,000 = 10³, so each "binary rung" lines up almost exactly with each "decimal rung." That's why you can think in round thousands (KB, MB, GB, TB) without worrying about the ~2.4% drift per rung — for ballpark work it never matters. The third line shows the inverse trick: given a per-day total, dividing by ~10⁵ seconds/day converts it to a per-second rate, so 100 GB/day ÷ 86,400 s ≈ 1 MB/s average throughput.

Worked — "How big is Twitter's timeline storage?"

200M DAU × 100 tweets/day = 2 × 10¹⁰ tweets/day. At 300 bytes per tweet record → 6 TB/day → ~2 PB/year. Confirms "we need partitioning + tiered storage." That's the senior signal: the number tells you the architecture.

A second worked example — sizing an image-upload service

The Twitter example was about text, where each record is tiny. Estimates feel different when the payload is large, so let's trace a fresh one end to end: "We're building a photo-sharing app. How much storage do we add per day, and what write throughput do we need?" Watch how the exact same users × actions × size decomposition handles a totally different domain — and notice where a unit slip would quietly wreck the answer.

  • Users (state the assumption): 100M DAU → 10⁸ daily active users. "I'll assume 100 million — correct me if it's an order of magnitude off."
  • Actions per user: assume each user uploads ~2 photos/day. Uploads/day = 10⁸ × 2 = 2 × 10⁸ photos/day (200 million).
  • Size per action: a phone photo is ~2 MB. Don't write "2" — write the bytes: 2 MB = 2 × 10⁶ bytes. This is the step where people trip: forgetting that "MB" hides six zeros is a classic unit error.
  • Storage per day: 2 × 10⁸ photos × 2 × 10⁶ bytes = 4 × 10¹⁴ bytes/day. Multiply front digits (2 × 2 = 4), add exponents (8 + 6 = 14). Now read the rung: 10¹² is a TB, so 10¹⁴ is 100 TB, and 4 × 10¹⁴ = 400 TB/day.
  • Write throughput: 4 × 10¹⁴ bytes/day ÷ 10⁵ seconds/day = 4 × 10⁹ bytes/s ≈ 4 GB/s sustained (subtract exponents: 14 − 5 = 9, and 10⁹ = 1 GB). Add a ~2× peak factor and you're sizing ingest for ~8 GB/s at the busy hour.
  • Scale up: 400 TB/day × 365 ≈ 146,000 TB ≈ ~150 PB/year (and that's before backups or replicas, which typically multiply it by 2–3×).

Now sanity-check it. 400 TB/day is ~70× the Twitter number (6 TB/day) even though Twitter has 2× the users and 50× the actions. Does that make sense? Yes — a 2 MB photo is ~7,000× bigger than a 300-byte tweet, and that single factor swamps everything else. The check confirms the dominant term and catches you if you'd accidentally written photos at "2 bytes" instead of 2 MB. The architecture falls out of the number: 4 GB/s of writes and 150 PB/year means you don't store blobs in your database at all — you push the bytes to object storage (S3-style) and keep only small metadata rows in the DB, exactly the opposite tradeoff from the text-heavy Twitter case.

Why this matters, and the pitfalls that sink estimates

Estimation matters because scale changes the design, and only a number reveals the scale. The same feature ("store user posts") is a single Postgres table at 10 GB/year and a sharded, tiered, multi-region system at 2 PB/year — and you cannot tell which one you're building until you've done 30 seconds of math. Interviewers probe estimation precisely because it predicts whether you'll over-engineer a toy or under-build something that falls over in production. The deadly mistakes are almost never arithmetic — they're powers-of-ten slips and unit errors:

  • Dropped a rung (off by 1000×). Confusing MB with GB, or 10⁹ with 10¹², instantly throws you off by a factor of a thousand. The fix: always carry units explicitly (write "2 × 10⁶ bytes," never bare "2 MB" inside a multiplication) and re-read which rung your final exponent lands on.
  • Adding exponents when you should subtract (or vice versa). Multiply → add exponents; divide → subtract. A per-day-to-per-second conversion is a division by 10⁵, so the exponent goes down by 5. Writing it as +5 makes your QPS 10¹⁰× too big.
  • Forgetting time entirely. "6 TB" is meaningless without "/day" or "/year." A rate (per second) and a total (lifetime) differ by ~3 × 10⁷ for a year — always tag every quantity with its time unit.
  • Confusing average with peak. Sizing only for average QPS leaves you crushed at the busy hour. Apply a peak factor (~2–10×) before choosing capacity.
  • Forgetting overhead multipliers. Raw payload isn't the whole bill: replication (often ×3), backups, indexes, and protocol overhead can multiply storage 2–5×. Mention them even if you only roughly fold them in.
  • Skipping the sanity check. Always end by asking "is this number physically plausible?" A chat app at 100 PB/day, or a single laptop "serving" 50 GB/s, is a red flag to re-derive — you almost certainly slipped a rung.

Key idea in one sentence: estimation is not about being right, it's about being in the right order of magnitude fast — close enough to pick the correct architecture, derived transparently enough that the interviewer can follow and correct every step.

Decompose, don't guess

Total = users × actions × size. Each factor is easier to estimate than the whole.

Round aggressively

Ballpark — 200M → 2×10⁸. Don't carry 4 significant digits.

State assumptions

"Assuming 1KB per row" — interviewer corrects you if needed. Locks the basis.

Sanity-check

100 PB/day for a chat app? You're off by 1000×. Re-derive.

Takeaway: every back-of-envelope estimate is two moves — decompose the answer into quantity × rate × size, then multiply in scientific notation (multiply front digits, add exponents; subtract exponents to divide by time). Memorize the ladders (×1000 per storage rung KB→MB→GB→TB→PB; the latency table ns→µs→ms), always carry units, distinguish average from peak, and finish with a plausibility check. The deliverable isn't the number — it's the architectural decision the number forces.

→ Going deeper: Estimation rounds assume comfort with orders of magnitude. See Math toolkit.
→ Going deeper: Back-of-envelope math feeds capacity planning. See Scaling primitives.