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.
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:
| Value | Rounded | |
|---|---|---|
| Seconds in a day | 86,400 | ~10⁵ |
| Seconds in a month | 2.6 million | ~2.5 × 10⁶ |
| 1 million requests/day | 11.6/s | ~12/s |
| 1 billion requests/day | 11,600/s | ~12,000/s |
Latency, to the nearest order of magnitude (see latency numbers for more):
| Operation | Time |
|---|---|
| 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):
| Component | Ballpark |
|---|---|
| Stateless API server (Go, simple JSON) | 5,000–20,000 requests/s |
| PostgreSQL, indexed primary-key reads | 10,000–50,000 queries/s |
| PostgreSQL, single-row writes | 2,000–10,000/s, limited by fsync and indexes |
| Redis, simple GET/SET | ~100,000 operations/s per core |
| Network interface | 10–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.
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 secondThe 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:
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:
cache size ≈ distinct items read per day × 0.2 × bytes per itemConcurrency 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:
concurrent requests in flight = arrival rate × time each request takesAt 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.
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:1Storage.
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:
45,000/s × 200 KB = 9 GB/s ≈ 72 Gbit/s at peakWhat the numbers decide:
- 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.
- 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.
- 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.
- 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.A service gets 500 million requests a day. Roughly how many per second on average?
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.A video service streams at 5 Mbit/s to 200,000 concurrent viewers. What is the egress bandwidth?
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.
- Latency numbers to knowMemory, SSD, network and cross-region round trips, to the nearest order of magnitude.
- Capacity estimationFrom daily users to requests per second, storage and bandwidth in a few lines of arithmetic.
- Little's lawWork in progress equals throughput times latency — the formula behind pool, queue and fleet sizes.
- Tail latencyWhy p99 matters more than the average, how fan-out amplifies it, and hedged requests.
- Wirth's lawSoftware gets slower faster than hardware gets faster, so the speed users feel tends to stand still.
Finished reading?
Mark it complete to fill in your roadmap.