Capacity Estimation (Back-of-Envelope Math)

Why this step exists

Before choosing a database or deciding whether sharding is needed, the actual numbers matter — a system serving 10 requests/second and one serving 100,000 requests/second need genuinely different architectures, and guessing which regime a problem is in (instead of computing it) is how a design ends up wildly over- or under-engineered. This is arithmetic, not a memorized fact — the goal is deriving concrete numbers from the requirements gathered in step 1, not recalling a specific system's real-world numbers.

Reference numbers worth having memorized

Operation Approximate latency
L1 cache reference ~1 ns
RAM access ~100 ns
Redis / in-memory cache GET ~0.1-1 ms
SSD random read ~100 µs
Same-datacenter network round trip ~0.5 ms
HDD seek ~5-10 ms
Cross-region network round trip ~50-150 ms

The relative gaps matter more than the exact numbers: RAM is roughly 1,000x faster than SSD, and a same-region network call is roughly 1,000x faster than a cross-region one. These ratios are what justify caching (avoid the RAM-vs-SSD gap) and regional deployment (avoid the cross-region gap) as default design moves, not just conventional wisdom to cite without understanding why.

QPS (queries per second)

QPS_average = (daily active users) x (actions per user per day) / 86,400
QPS_peak    = QPS_average x peak_factor   (commonly 2x-3x)

86,400 is the number of seconds in a day — dividing total daily actions by it gives the average rate, which is why the peak factor matters: real traffic isn't uniform across 24 hours, and designing only for the average leaves the system unable to handle the actual busiest moments, which is when it matters most.

Read and write QPS are usually computed separately and are often wildly different ratios (100:1 read:write is common for content systems) — a single combined QPS number hides this and leads to under-provisioning whichever side is actually the bottleneck.

Storage

storage_per_day = (new records per day) x (size per record)
storage_over_N_years = storage_per_day x 365 x N x replication_factor

The replication_factor term is the one most often forgotten — a system storing 100TB of logical data with 3x replication (common for durability) actually needs 300TB of physical storage provisioned, not 100TB.

Bandwidth

bandwidth = QPS x average_request_or_response_size

Computed separately for ingress (writes) and egress (reads) — a read-heavy system's egress bandwidth is usually the dominant cost and capacity constraint, not ingress.

Worked example: URL shortener

Requirements: 100 million new URLs shortened per month, 100:1 read:write ratio (redirects vastly outnumber new shortens), each URL record is roughly 500 bytes, data retained for 5 years.

Write QPS: 100,000,000 / (30 x 86,400) ≈ 38.6 writes/second average. With a 2x peak factor: ~77 writes/second peak.

Read QPS: 100:1 ratio → 38.6 x 100 ≈ 3,860 reads/second average, ~7,720 reads/second peak.

Storage over 5 years: 100,000,000 x 12 x 5 = 6 billion records total, 6,000,000,000 x 500 bytes ≈ 3TB of logical data. With 3x replication: ~9TB physical storage needed.

What these numbers actually decide: ~77 writes/second is trivial for a single database — no need to shard for write throughput at this scale. ~7,720 reads/second is enough to make caching genuinely valuable (a cache serving hot URLs directly avoids most of that load hitting the database). 9TB is well within a single well-provisioned database server's capacity — sharding for storage reasons alone isn't justified yet at this scale, which directly informs the URL Shortener case study's design choices rather than assuming sharding is needed by default.

Common pitfall

Computing only the average QPS and using it to size infrastructure is the single most common estimation mistake — a system provisioned for average load falls over during exactly the traffic spikes it most needs to survive (a product launch, a viral post, a Black Friday sale). Always compute peak alongside average, and treat peak as the number that actually determines capacity, with average only useful for cost estimation.