Numbers Every Engineer Should Know
How long does it take to read a seat from memory? From an SSD? From a database in the same data centre? From a server in Virginia, while the fan is in SΓ£o Paulo? The answers span eight orders of magnitude β from a nanosecond to a hundred milliseconds β and most architectural rules of thumb ("cache it", "batch it", "don't call across regions synchronously") are just consequences of that spread. This page collects the numbers worth memorizing and shows how to turn them, together with a few assumptions about users, into requests per second, storage and bandwidth.
Powers of two (and ten)
Data sizes are powers of two; estimates are easier in powers of ten. Since 2ΒΉβ° = 1,024 β 10Β³, you can switch freely for estimation purposes:
| Power of two | Exact value | β Power of ten | Unit | Something that size |
|---|---|---|---|---|
| 2ΒΉβ° | 1,024 | 10Β³ (thousand) | 1 KB | a short JSON response; a seat record Γ10 |
| 2Β²β° | 1,048,576 | 10βΆ (million) | 1 MB | an event poster (compressed photo) |
| 2Β³β° | β 1.07 Γ 10βΉ | 10βΉ (billion) | 1 GB | a year of BoxOffice seat data (illustrative) |
| 2β΄β° | β 1.10 Γ 10ΒΉΒ² | 10ΒΉΒ² (trillion) | 1 TB | a large single-node database |
| 2β΅β° | β 1.13 Γ 10ΒΉβ΅ | 10ΒΉβ΅ (quadrillion) | 1 PB | a video platform's catalog |
Strictly, 2ΒΉβ° bytes is a kibibyte (KiB) and 10Β³ bytes a kilobyte (kB); the difference (2.4% at KB, 10% at TB) does not matter for back-of-the-envelope work.
Bits vs bytes
Network speeds are quoted in bits per second (a "10 Gbit/s" network interface), storage and payloads in bytes. Divide by 8: a 10 Gbit/s link carries at most 1.25 GB/s. Mixing the two is the most common estimation error.
Time
| Period | Seconds | Round to |
|---|---|---|
| 1 minute | 60 | β |
| 1 hour | 3,600 | 4 Γ 10Β³ |
| 1 day | 86,400 | 10β΅ |
| 1 month (30 days) | 2,592,000 | 2.5 Γ 10βΆ |
| 1 year | 31,536,000 | 3 Γ 10β· |
A handy conversion table, using 1 day β 10β΅ s (the exact factor is 86,400, which makes the real rates about 15% higher):
| Per day | β Per second (average) |
|---|---|
| 1 million | ~12 |
| 10 million | ~120 |
| 100 million | ~1,200 |
| 1 billion | ~12,000 |
Latency numbers every engineer should know
In 2009, Jeff Dean (Google) popularized a list of "numbers everyone should know" β the cost of basic operations in a computer and a network1. Hardware has changed since (SSDs replaced spinning disks on the hot path, networks got faster), but the ratios have stayed remarkably stable, because some limits β the speed of light, the physics of memory β do not improve. The table uses 2020s orders of magnitude, compiled from Dean's list, its later updates2 and Gregg's Systems Performance3; your hardware may differ by 2β3Γ, which is fine for estimates.
| Operation | Latency (order of magnitude) | If 1 ns were 1 second⦠|
|---|---|---|
| L1 cache reference | ~1 ns | 1 s |
| Branch mispredict | ~3 ns | 3 s |
| L2 cache reference | ~4 ns | 4 s |
| Mutex lock/unlock (uncontended) | ~20 ns | 20 s |
| Main memory (RAM) reference | ~100 ns | 1.7 min |
| Compress 1 KB with a fast compressor | ~2 Β΅s | 33 min |
| Read 1 MB sequentially from RAM | ~10β50 Β΅s | 3β14 h |
| Random 4 KB read from an NVMe SSD | ~20β100 Β΅s | 6β28 h |
| Round trip inside one data centre / availability zone | ~0.1β0.5 ms | 1β6 days |
| Read 1 MB sequentially from an NVMe SSD | ~0.2 ms | 2.3 days |
Redis GET or primary-key SQL query, same zone (mostly network) | ~0.2β1 ms | 2β12 days |
| Round trip between availability zones of one region | ~1β2 ms | 12β23 days |
| Spinning disk (HDD) seek | ~5β10 ms | 2β4 months |
| Read 1 MB sequentially from an HDD | ~5 ms | 2 months |
| Round trip SΓ£o Paulo β US East (Virginia) | ~110β130 ms | ~4 years |
| Round trip across the Atlantic / Pacific | ~80β200 ms | 3β6 years |
| TCP + TLS handshake to a far server | 2β3 round trips | β |
What the table teaches
- Memory is ~1,000Γ faster than SSD, and SSD ~100Γ faster than HDD for random reads. This is why caches (Redis keeps everything in RAM) and in-memory indexes exist.
- Inside a data centre, the network costs more than the work. A Redis
GETtakes microseconds of CPU on the server; the round trip is what you wait for. A page that makes 50 sequential calls to Redis spends ~10β25 ms just on round trips β batch them (MGET, pipelining) or cache in process. - Across regions, physics wins. Light in optical fibre travels at about 200,000 km/s, i.e. ~5 Β΅s per km, so every 100 km adds about 1 ms of round trip before any router or server touches the packet. SΓ£o Paulo to Virginia is ~7,500 km in a straight line, so the theoretical minimum round trip is ~75 ms; real routes give ~110β130 ms. No technology removes this: avoid synchronous cross-region calls on the critical path and serve users from nearby (CDN, regional deployments).
- Sequential beats random. Reading 1 MB sequentially from an SSD costs about as much as a few random 4 KB reads. Log-structured storage, Kafka's append-only log and batch processing all exploit this.
- Round trips add up; bandwidth rarely limits small requests. For a 2 KB API response, latency is dominated by round trips (connection setup, TLS, the request itself), not by transfer time. Reusing connections (keep-alive, HTTP/2) matters more than a fatter pipe.
BoxOffice β the seat map, three ways
The seat map of a stadium event needs ~60,000 seat states.
- 60,000 individual queries from the app to PostgreSQL in the same zone: 60,000 Γ ~0.5 ms β 30 s. Unusable.
- One query returning 60,000 rows of ~50 bytes (3 MB): one round trip + ~10β30 ms of database work + ~3 ms to transfer over a 10 Gbit/s link β 20β40 ms.
- One cached, compressed blob in Redis (~300 KB after compression), refreshed every second: one round trip + a fraction of a millisecond of transfer β 1β2 ms.
Same data, four orders of magnitude apart β decided entirely by the number of round trips and where the data lives.
Throughput rules of thumb
Latency tells you how long one operation takes; capacity planning also needs how many operations per second a component can sustain. These vary much more with hardware, configuration and workload than latencies do, so treat the table as illustrative starting assumptions that you must replace with measurements (that is what lab 2 is for):
| Component | Order of magnitude (simple operations, one node) | What limits it |
|---|---|---|
| App server (JVM, simple JSON endpoint) | 10Β³β10β΄ requests/s | CPU per request, threads, downstream calls |
| Nginx serving cached/static content | 10β΄β10β΅ requests/s | CPU, network |
| Relational database, primary-key reads | 10β΄β10β΅ queries/s | CPU, buffer cache hit ratio |
| Relational database, durable write transactions | 10Β³β10β΄ commits/s | log flush (fsync), locks |
Redis, simple GET/SET | ~10β΅ operations/s per instance | single-threaded command loop, network |
| Kafka, one partition | ~10 MB/s order of magnitude | disk, network, replication |
| 10 Gbit/s network interface | 1.25 GB/s | the wire |
The pattern to remember: reads are cheaper than durable writes, memory is cheaper than disk, and anything that must flush to disk or cross the network to commit (durable writes, replication, consensus) has a lower ceiling.
Typical sizes
| Item | Size | Note |
|---|---|---|
| Boolean / byte | 1 B | β |
| Integer / timestamp | 4β8 B | bigint, epoch millis |
| UUID | 16 B (36 B as text) | store binary when you can |
| Short string (name, e-mail) | 20β100 B | UTF-8 |
| BoxOffice seat row | ~100 B | ids, status, price, hold id, version |
| BoxOffice order | ~1 KB | with items and payment reference |
| BoxOffice event (description, metadata) | ~2β5 KB | β |
| JSON API response (a page of results) | 2β50 KB | before compression |
| Ticket PDF | ~100 KB | β |
| Compressed photo (poster) | 200 KB β 2 MB | multiple resolutions |
| 1 minute of HD video | 50β100 MB | depends on bitrate |
| One embedding vector (1,024 dims Γ 4 B) | ~4 KB | relevant for vector DBs (class 13) |
Two multipliers are easy to forget: replication (a database usually keeps 3 copies; object stores replicate internally) and indexes and overhead (often 1.5β2Γ the raw data in a relational database).
Estimating requests per second (QPS)
QPS (queries per second, used loosely for requests per second) is the starting point of every capacity estimate:
- Peak factor: traffic is not flat over the day. For consumer products the busiest hour is typically 2β3Γ the daily average; that is the number you size for. For event-driven businesses, the peak is a spike that has nothing to do with the daily average β estimate it separately.
- Read/write ratio: split the actions into reads and writes. Reads can be cached and replicated; writes go to a primary. A product at 100:1 and one at 1:1 are different designs.
BoxOffice β requests per second (assumptions in italics)
Normal day
- 20 M registered fans, 2 M daily active; each views ~20 pages (events, seat maps, searches).
- Reads: 2 M Γ 20 = 4 Γ 10β· per day β 4 Γ 10β· / 10β΅ β 400 reads/s average.
- Peak hour β 3Γ average β ~1,200 reads/s.
- Writes: 100 k orders/day, each ~5 writes (hold, order, payment, tickets, outbox) β 5 Γ 10β΅ / 10β΅ β 5 writes/s average, ~15 at peak.
- Read/write ratio β 100:1 β cache and replicate reads; a single primary handles writes easily.
On-sale spike
- 2 M fans arrive in the first 60 s; each sends ~3 requests in that minute (page, refresh, hold attempt).
- 2 Γ 10βΆ Γ 3 / 60 β 100,000 requests/s at the edge β ~80Γ the normal peak, for a few minutes.
- Only 60 k seats exist: at most ~30 k fans can succeed (2 seats each). Almost all of the spike must be absorbed before it reaches the inventory: CDN for static content, cache for the event page, waiting room for holds.
Estimating storage
BoxOffice β storage for 5 years
| Data | Volume | Size each | Per year | 5 years, Γ3 replicas | Store |
|---|---|---|---|---|---|
| Orders | 100 k/day | 1 KB | 100 MB/day Γ 365 β 37 GB | β 550 GB | SQL |
| Seats | 20 k events/year Γ 5 k seats = 10βΈ rows | 100 B | 10 GB | β 150 GB | SQL (hot only during on-sale) |
| Ticket PDFs | 200 k tickets/day | 100 KB | 20 GB/day β 7 TB | object store (replicated internally) β 35 TB | Object Store |
| Event images | 20 k events Γ 5 images | 1 MB | 100 GB | β 0.5 TB | Object Store + CDN |
| Access logs | 10βΈ requests/day | 500 B | 50 GB/day β 18 TB | keep 30 days hot β 1.5 TB | log platform / object store |
Conclusions: the transactional data (orders, seats) is well under a terabyte even after 5 years with replicas β a single PostgreSQL primary with replicas fits; sharding is not a day-one requirement. The bulky data is files and logs, which belong in an object store (cheap, durable, effectively unlimited) β and you might decide to generate ticket PDFs on demand instead of storing 35 TB of them.
Estimating bandwidth
BoxOffice β bandwidth at the normal peak
- API responses: 1,200 req/s Γ 20 KB β 24 MB/s β 0.2 Gbit/s β trivial for the origin.
- Images: each page view loads ~1 MB of images β 1,200 Γ 1 MB β 1.2 GB/s β 10 Gbit/s β saturates a 10 Gbit/s link and costs a lot in egress. Serve images from a CDN: with a 95% edge hit ratio, the origin sends only ~0.5 Gbit/s.
- On-sale spike: 100 k req/s Γ 5 KB (a lightweight waiting-room page) β 500 MB/s β 4 Gbit/s β must be served from the edge (CDN or edge compute), not from the app servers.
Estimating servers and memory
Once you know the peak load and the per-node capacity, the number of nodes follows β with headroom and redundancy:
- Target utilization of 60β75% for latency-sensitive services β the queueing page explains why running closer to 100% destroys p99.
- Spares (N+1, N+2): if one node fails or is being deployed, the others must absorb its load without crossing the knee.
For cache memory, a common rule of thumb is the 80/20 rule: a small fraction of the items receives most of the traffic, so caching the hot set β often ~20% of the items, sometimes far less β captures most of the reads.
BoxOffice β catalog servers and cache
- One catalog instance handles ~1,000 req/s at 100% CPU (to be measured). Peak 1,200 req/s at 60% target β 1,200 / 600 = 2 β 2 + 1 spare = 3 instances.
- Hot set: the ~2,000 events on sale this month Γ 5 KB (event JSON) + seat-map summaries (~300 KB each) β 10 MB + 600 MB β ~0.6 GB β fits in a small Redis instance with a replica.
In the BoxOffice code: one node, sized and then measured (labs 1 and 2)
The estimate above assumes 1,000 req/s per catalog instance. The labs replace the assumption with a measurement. Hands-on 1 fixes the size of one node β 1 CPU, 768 MB and a pool of 10 database connections β and Hands-on 2 measures what it serves: in the lab's example run, p99 stayed under 40 ms up to 300 req/s, reached 224 ms at 400 req/s and 2 s at 500 req/s. Capacity with p99 < 300 ms is therefore ~400 req/s, not 1,000. Redo the line: 1,200 / (400 Γ 0.6) = 5 β 5 + 1 spare = 6 instances, twice the first answer β and lab 3 shows they help only while the shared PostgreSQL keeps up.
catalog:
build: ./services/catalog
environment:
DB_HOST: db
DB_PORT: 5432
DB_NAME: ${DB_NAME:-boxoffice}
DB_USER: ${DB_USER:-boxoffice}
DB_PASSWORD: ${DB_PASSWORD:-boxoffice}
DB_POOL_SIZE: ${DB_POOL_SIZE:-10} # HikariCP pool size (lab 2 experiments with it)
ports:
- "8082:8082"
depends_on:
db:
condition: service_healthy # wait until PostgreSQL accepts connections
deploy:
resources:
limits:
cpus: "1.0" # one core per replica: makes scaling visible in lab 3
memory: 768M
Think first: estimate a URL shortener
100 M new short URLs per month; reads are 100Γ writes; each record ~500 B; keep for 5 years.
Answer sketch
- Writes: 10βΈ / (2.5 Γ 10βΆ s) β 40 writes/s; reads β 4,000 reads/s (peak Γ2β3 β ~10 k/s).
- Storage: 10βΈ Γ 12 Γ 5 = 6 Γ 10βΉ records Γ 500 B = 3 TB (β 9 TB with 3 replicas).
- Implications: reads dominate and are highly cacheable (popular links) β cache; 3 TB is large for one node's working set, so plan partitioning or a key-value store; key space: 6 Γ 10βΉ URLs need β₯ 6 characters in base 62 (62βΆ β 5.7 Γ 10ΒΉβ°). The case study develops it.
In the interview
Carry a small "numbers card" in your head: 1 day β 10β΅ s; 1 M/day β 12/s; RAM ~100 ns; SSD ~100 Β΅s; same-zone round trip ~0.5 ms; cross-continent ~100+ ms; 1 Gbit/s β 125 MB/s. Write assumptions before results, round everything to one significant digit, and finish every line with its consequence. If you are unsure of a number, say so and give a range: "a primary-key lookup is around a millisecond including the network β let's say 1 ms."
Best practices
- Keep units on every line and one significant digit in every result β "4 Γ 10β· reads/day β 400 reads/s"; units catch most mistakes before they reach a decision.
- Replace each rule-of-thumb capacity with a measured one before you size a fleet β the measurement is cheap, the wrong fleet is not. In BoxOffice: lab 2's ~400 req/s replaced the assumed 1,000 (box above).
- Fix the CPU and memory of every container β limits make "capacity per node" a property of the deployment, not of whoever's laptop ran the test. In BoxOffice:
cpus: "1.0"andmemory: 768Min lab 1's compose. - Put egress next to bandwidth β every gigabyte that leaves the cloud is billed; the CDN's hit ratio and the egress price belong in the same row of the sheet.
- Keep a team numbers card with the source of each number β latencies, throughputs and prices change with hardware and providers; a dated source tells you when to refresh it.
Common pitfalls
- Treating latency numbers as exact: they are orders of magnitude; your hardware and your cloud will differ.
- Forgetting round trips: 100 sequential calls at 0.5 ms are 50 ms, even if each call does almost nothing.
- Sizing for the daily average instead of the peak β or forgetting the spike altogether.
- Ignoring replication, indexes and retention in storage.
- Bits vs bytes, and 86,400 vs 10β΅ when precision matters (e.g. SLA calculations β use the exact value there).
How it connects
flowchart LR
P2["powers of two and ten<br/>1 day β 10β΅ s"] --> QPS["QPS: average and peak<br/>the spike estimated apart"]
LAT["latency numbers<br/>RAM, SSD, network"] --> CACHE["cache the hot set<br/>β Caching"]
LAT --> RT["count round trips<br/>β Edge protocols"]
QPS --> NODES["nodes = peak / capacity Γ U<br/>+ spares β Compute"]
QPS --> BW["bandwidth = QPS Γ size<br/>β CDN"]
SIZES["typical sizes"] --> STO["storage Γ retention<br/>Γ replication"]
STO --> SHARD["shard or not?<br/>β Databases"]
STO --> OBJ["bulky files and logs<br/>β object store"]
NODES --> KNEE["target utilization<br/>β Queueing"] Palette components: app (instances = peak / capacity per node, plus spares) Β· sql (orders and seats stay under a terabyte; the durable-write ceiling) Β· cache (the hot set, ~0.6 GB for the catalog) Β· cdn (image bandwidth off the origin) Β· objstore (ticket PDFs, images, logs) Β· kafka (~10 MB/s per partition) Β· vectordb (~4 KB per embedding). Scenarios: monolith, read-heavy-cache, cdn-static, url-shortener. Continues in: Queueing, Edge β DNS & CDN, Caching, Databases β partitioning, Case study: URL shortener, Exercise: estimation.
Key takeaways
- 2ΒΉβ° β 10Β³; 1 day β 10β΅ s; 1 M per day β 12 per second.
- Latencies span eight orders of magnitude: RAM ~100 ns, SSD ~100 Β΅s, same-zone network ~0.5 ms, cross-continent ~100 ms; most design rules follow from these ratios.
- QPS = users Γ actions / 86,400 Γ peak factor; estimate spikes separately.
- Storage = items Γ size Γ retention Γ replication (Γ overhead); bandwidth = QPS Γ size.
- Nodes = peak / (capacity Γ target utilization) + spares; cache the hot set.
-
DEAN, J. Designs, Lessons and Advice from Building Large Distributed Systems. Keynote, LADIS workshop, 2009 ("numbers everyone should know").Β β©
-
SCOTT, C. Latency numbers every programmer should know (interactive), University of California, Berkeley.Β β©
-
GREGG, B. Systems Performance: Enterprise and the Cloud, 2nd ed. Addison-Wesley, 2020. Chapter 2 (methodologies: latency scale and known numbers).Β β©