Step 02 of 22

Back-of-the-envelope estimation

Estimate requests per second, storage, bandwidth, memory and machine counts in minutes, and use the results to make design decisions.

18 min 9 sections

Before you can say "one database is enough" or "this needs sharding", you need numbers. Not precise ones — numbers within a factor of two or three, which you can get in five minutes with round figures and multiplication. This lesson gives you the reference values worth memorising, a method for each kind of estimate, and a full worked example that ends in real design decisions.

Why rough numbers are enough

Design decisions change at order-of-magnitude boundaries. Whether you need one server or two rarely changes the architecture. Whether you need one server or two hundred changes everything. So the goal is the right power of ten, quickly, with your assumptions written down so others can challenge them.

Three habits make estimates trustworthy:

  • Round aggressively. A day has 86,400 seconds; call it 100,000 (10⁵). You'll be 15% high, which is noise next to the uncertainty in your user count.
  • Write every assumption on its own line. "500 million daily users, 20% post once a day" can be argued with. A bare final number can't.
  • Sanity-check against something real. If your estimate says a chat app needs more servers than Google, re-check the units.

Numbers worth memorising

Time and rate conversions:

ValueRounded
Seconds in a day86,400~10⁵
Seconds in a month2.6 million~2.5 × 10⁶
1 million requests/day11.6/s~12/s
1 billion requests/day11,600/s~12,000/s

Latency, to the nearest order of magnitude (see latency numbers for more):

OperationTime
Read from main memory~100 ns
Read 1 MB sequentially from memory~10–50 µs
Random read from an NVMe SSD~20–100 µs
Round trip inside one data centre~0.1–0.5 ms
Read 1 MB sequentially from an NVMe SSD~0.2–1 ms
Round trip across a continent~40–80 ms
Round trip across the Atlantic or Pacific~80–150 ms

Rough single-machine capacities (modern server, simple workload — treat as starting points, then measure):

ComponentBallpark
Stateless API server (Go, simple JSON)5,000–20,000 requests/s
PostgreSQL, indexed primary-key reads10,000–50,000 queries/s
PostgreSQL, single-row writes2,000–10,000/s, limited by fsync and indexes
Redis, simple GET/SET~100,000 operations/s per core
Network interface10–25 Gbit/s ≈ 1–3 GB/s

These numbers move with hardware, payload size and query shape by 10× in either direction, which is exactly why you write them down as assumptions.

Traffic: from users to requests per second

Start from users and actions, then convert to per-second rates.

text
daily active users (DAU)      × actions per user per day   = actions per day
actions per day / 10^5        = average per second
average × peak factor (2–10×) = peak per second

The peak factor matters more than people expect. Traffic follows the sun, spikes on events, and bursts when a mobile push notification lands on millions of phones at once. Size for the peak, not the average.

Split reads from writes, because they scale differently. Reads can be served from caches and replicas; writes must reach the system of record. A 100:1 read-to-write ratio and a 1:1 ratio lead to very different designs.

Storage, bandwidth and memory

Storage is records per day × size per record × retention, plus overheads:

text
new records per day × bytes per record × days retained
  × replication factor (often 3)
  × index and format overhead (1.2–2×)

Bandwidth is requests per second × bytes per response. 2,000 image requests per second at 200 KB each is 400 MB/s, or 3.2 Gbit/s: one network card can carry it, but your cloud egress bill will notice. Data leaving a cloud provider typically costs a few cents per gigabyte, so bandwidth estimates are cost estimates too.

Memory for a cache usually follows the 80/20 rule: a small fraction of items gets most of the reads. Caching the hottest 20% of a day's reads is a common starting point:

text
cache size ≈ distinct items read per day × 0.2 × bytes per item

Concurrency and machine counts

Requests per second alone doesn't tell you how many machines you need. Concurrency does, and Little's law connects the two:

text
concurrent requests in flight = arrival rate × time each request takes

At 10,000 requests per second with 50 ms average latency, 500 requests are in flight at any moment. If each instance comfortably handles 100 concurrent requests, you need 5 instances, then add headroom: run at 50–70% of capacity so a traffic spike or the loss of one instance doesn't tip you over. The same law sizes database connection pools: 2,000 queries per second at 5 ms each keeps 10 connections busy, so a pool of 20–30 is plenty and a pool of 500 is waste.

Worked example: a photo-sharing service

Assumptions, each on its own line:

  • 50 million daily active users.
  • 10% upload one photo a day → 5 million uploads/day.
  • Each user views 30 photos a day → 1.5 billion views/day.
  • Average photo, after compression, with a few resized versions: 2 MB total.
  • Keep photos forever. Peak factor 3×.

Traffic.

text
uploads: 5 × 10^6 / 10^5      ≈ 50/s average, ~150/s peak
views:   1.5 × 10^9 / 10^5    ≈ 15,000/s average, ~45,000/s peak
read:write ratio              ≈ 300:1

Storage.

text
per day:  5 × 10^6 × 2 MB     = 10 TB/day
per year: 10 TB × 365         ≈ 3.65 PB/year (before replication)

Bandwidth for views. Most views load a 200 KB thumbnail-sized version:

text
45,000/s × 200 KB             = 9 GB/s ≈ 72 Gbit/s at peak

What the numbers decide:

  1. The images can't be served from your own servers. 72 Gbit/s of egress is a CDN's job. Your servers will see mostly cache misses.
  2. The images can't live in a database. 3.65 PB a year belongs in object storage; the database stores metadata (owner, keys, captions), which is tiny by comparison: 5 million rows a day × 500 bytes ≈ 2.5 GB a day.
  3. The metadata database is read-heavy. At 300:1, read replicas and a cache will absorb the reads; 150 writes per second is easy for a single primary.
  4. Uploads should go straight to object storage with presigned URLs, so 150 uploads per second of 2 MB each — 300 MB/s — never passes through your API servers.

Four architecture decisions, each traceable to a line of arithmetic. That is what estimation is for.

Common mistakes

  • Mixing up bits and bytes. Network speeds are in bits (Gbit/s); storage and file sizes are in bytes. Divide by 8.
  • Forgetting replication and indexes. Three replicas triples raw storage; indexes often add 20–100%.
  • Sizing for the average. Real traffic peaks at 2–10× the daily mean.
  • False precision. "We need 47.3 servers" signals that you trusted inputs that were guesses. Say "around 50, assuming…".

Practice

Estimate a URL shortener with these assumptions: 100 million new short links a month, a 100:1 redirect-to-create ratio, each link record about 500 bytes, links kept for 10 years, and a peak factor of 5×.

Work out: (1) creates and redirects per second, average and peak; (2) total storage after 10 years, before and after 3× replication; (3) the cache size needed to hold the hottest 20% of a day's redirected links; (4) one design decision each number supports.

Show solution

1. Traffic. 100 million creates a month / 2.5 × 10⁶ seconds ≈ 40 creates/s average, 200/s peak. Redirects are 100× that: 4,000/s average, 20,000/s peak.

2. Storage. 100 million × 12 months × 10 years = 12 billion links. 12 × 10⁹ × 500 B = 6 TB. With 3× replication, 18 TB. Large but ordinary: it fits a handful of database nodes, or one large one with room to spare for a few years.

3. Cache. A day has about 4,000 × 10⁵ = 400 million redirects. If they touch, say, 100 million distinct links, caching 20% means 20 million entries × 500 B = 10 GB, which fits in the memory of a single Redis node (with a replica for availability).

4. Decisions. 200 creates per second at peak means writes don't need sharding at first. 20,000 redirects per second at peak is too many to send to one database comfortably, but a 10 GB cache that catches most of them makes the database's share small. 6 TB growing to 18 TB with replicas means planning a partitioning scheme by link key before year three, not on day one.

Key takeaways

  • Aim for the right order of magnitude, quickly, with every assumption written down.
  • Convert users to requests per second (÷ 10⁵ per day), split reads from writes, and multiply by a peak factor.
  • Storage = records × size × retention × replication × overhead; bandwidth = requests per second × response size.
  • Little's law turns throughput and latency into concurrency, which sizes fleets and connection pools. Plan to run at 50–70% of capacity.
  • Every estimate should end in a decision: CDN or not, database or object storage, one node or many.

Check yourself

Quiz

0/4 correct · 4 left

  1. 1.A service gets 500 million requests a day. Roughly how many per second on average?

  2. 2.An API handles 4,000 requests per second with an average latency of 25 ms. How many requests are in flight at once?

  3. 3.A video service streams at 5 Mbit/s to 200,000 concurrent viewers. What is the egress bandwidth?

  4. 4.Why should you plan to run servers at 50–70% of capacity rather than 100%?

Concepts in this lesson

One-page notes on each idea, for review or a quick lookup later.

Finished reading?

Mark it complete to fill in your roadmap.