Back-of-the-Envelope Estimation
Estimates answer one question: which part of this system is hard? A system with 50 writes per second and one with 500,000 need completely different designs. You don’t need precise numbers, only the right order of magnitude.
The numbers to memorise
Time
| Period | Seconds | Use as |
|---|---|---|
| 1 day | 86,400 | 10⁵ |
| 1 month | ~2.6 million | 2.5 × 10⁶ |
| 1 year | ~31.5 million | 3 × 10⁷ |
Powers of two and data sizes
| Power | Approx. | Name |
|---|---|---|
| 2¹⁰ | 10³ | 1 KB (thousand) |
| 2²⁰ | 10⁶ | 1 MB (million) |
| 2³⁰ | 10⁹ | 1 GB (billion) |
| 2⁴⁰ | 10¹² | 1 TB (trillion) |
| 2⁵⁰ | 10¹⁵ | 1 PB |
Typical sizes: a character is 1 byte (ASCII) or up to 4 (UTF-8), an int 4 bytes, a long/timestamp 8 bytes, a UUID 16 bytes, a tweet-sized text ~300 bytes, a compressed photo 200 KB – 2 MB, a minute of 720p video ~25–50 MB.
Latency (orders of magnitude, from the classic “latency numbers every programmer should know”):
| Operation | Time |
|---|---|
| L1 cache reference | ~1 ns |
| Main memory reference | ~100 ns |
| Read 1 MB sequentially from memory | ~10 µs |
| Round trip within a data centre | ~0.5 ms |
| Read 1 MB sequentially from SSD | ~1 ms |
| HDD disk seek | ~10 ms |
| Round trip India ↔ US | ~150–250 ms |
The lessons from this table: memory is about 100× faster than SSD and network, so caches matter; cross-continent round trips are expensive, so CDNs and regional deployments matter.
What one machine can do (very rough, for a modern server): a well-tuned web server handles a few thousand to tens of thousands of simple requests per second; a single relational database handles a few thousand to ~10K writes per second and more reads; Redis handles ~100K operations per second per node.
The method
- Start from daily active users (DAU) and actions per user per day.
- Requests per day = DAU × actions.
- Average QPS = requests per day ÷ 10⁵.
- Peak QPS ≈ 2–3 × average (more for spiky events like a sale or a cricket final).
- Storage per day = writes per day × size of each write. Multiply by days kept and by the replication factor (usually 3).
- Bandwidth = QPS × size of each response.
Worked example: a photo-sharing app
Assume 50 million DAU. Each user views 100 photos and uploads 0.2 photos a day. A photo is 1 MB after compression, plus 1 KB of metadata.
Writes: 50×10⁶ × 0.2 = 10⁷ uploads/day → 10⁷ / 10⁵ = 100 uploads/s average, ~300/s peak.
Reads: 50×10⁶ × 100 = 5×10⁹ views/day → 5×10⁹ / 10⁵ = 50,000 views/s average, ~150,000/s peak.
So reads outnumber writes 500 to 1. The hard part is serving photos fast, not storing them. That points at a CDN and caching.
Storage: 10⁷ photos × 1 MB = 10 TB/day → × 365 ≈ 3.65 PB/year, × 3 replicas ≈ 11 PB/year. Metadata: 10⁷ × 1 KB = 10 GB/day, which fits easily in a database.
So photos go to object storage (like S3), metadata goes to a database.
Bandwidth out: 50,000 views/s × 1 MB = 50 GB/s, which is far too much to serve from our own servers. Again: CDN.
Cache: by the 80/20 rule, 20% of photos get 80% of views. Caching a day’s hot metadata: 0.2 × 5×10⁹ views × 1 KB ≈ 1 TB, which is spread across a small Redis cluster.
flowchart TB A["50M DAU"] --> R["Reads: 5×10⁹/day ≈ 50K/s"] A --> W["Writes: 10⁷/day ≈ 100/s"] R --> X["Read-heavy → CDN + cache"] W --> S["10 TB/day → object storage"]
Common traps
- Forgetting peak traffic. Systems are sized for the peak, not the average.
- Forgetting replication. Storage estimates are usually multiplied by 3.
- Mixing bits and bytes. Network speeds are in bits (1 Gbps ≈ 125 MB/s).
- Estimating everything. Only estimate what affects a decision. If writes are 100/s, you don’t need to estimate write bandwidth.
Check yourself
An app has 10 million daily active users who each make 20 requests a day. Roughly what is the average QPS?
Each upload stores a 2 MB photo and there are 1 million uploads a day. How much storage per year (ignoring replication)?
Which is fastest?
Item 2 of 25 · updated 2026-10-12