Fundamentals
Estimation practice
Three practice problems, photo sharing, chat and analytics events, each with its assumptions, arithmetic and the design conclusion it forces.
Practice is where the chain becomes automatic. Each problem lists its assumptions. Work it yourself before reading the answer, then compare.
Problem 1: photo sharing
An Instagram-like app. 50 million daily users. 10% upload one photo a day. Each upload stores the original (2 MB) plus resized variants totaling 500 KB. Each user views 100 photos a day, served as a 150 KB feed variant.
Uploads: 50M × 0.1 = 5M/day ÷ 86,400 ≈ 58 uploads/s (peak ~175)
Storage: 5M × 2.5 MB = 12.5 TB/day × 365 ≈ 4.6 PB/year
× ~1.4 erasure coding ≈ 6.4 PB provisioned (the object store handles this)
Metadata: 5M rows × 500 B = 2.5 GB/day ≈ 1 TB/year (about 2 TB with indexes)
Views: 50M × 100 = 5B/day ÷ 86,400 ≈ 58,000 views/s (peak ~170,000)
Egress: 58,000 × 150 KB ≈ 8.7 GB/s ≈ 70 Gbps average
× 86,400 ≈ 750 TB/dayConclusion: uploads are a small write rate, and the metadata fits in one relational database for years. Media goes to object storage. The view path is the problem: about 70 Gbps on average and over 200 Gbps at peak. That means a CDN. At an illustrative negotiated CDN rate of $0.01 to $0.02 per GB, 750 TB a day is roughly $7,500 to $15,000 a day.
Problem 2: chat
A messenger with 100 million daily users, each sending 40 messages a day. A message is 100 bytes of text plus 100 bytes of metadata. 30% of daily users are online at peak.
Messages: 100M × 40 = 4B/day ÷ 86,400 ≈ 46,000 msgs/s (peak ~140,000)
Storage: 4B × 200 B = 800 GB/day × 365 ≈ 290 TB/year × 3 ≈ 880 TB/year
Bandwidth: 46,000 × 200 B × 2 (in and out) ≈ 18 MB/s (trivial)
Connections: 100M × 30% = 30M concurrent ÷ 500,000 per server ≈ 60 gateways (about 100 with headroom)Conclusion: bandwidth is irrelevant for text. The hard parts are holding 30 million persistent connections (see real-time delivery) and absorbing 140,000 writes a second into a store that grows close to a petabyte a year. That points to a write-optimized store partitioned by conversation (see the chat system case study). WhatsApp publicly reported handling over 2 million connections on a single server back in 2012, so connection counts per box can be very high with the right runtime and kernel tuning.
Problem 3: analytics events
A product-analytics service. Customer sites send 20 billion events a day, each about 1 KB of JSON. Raw events are kept for 3 days for replay. Aggregates live in a columnar store that compresses about 10 times.
Ingest: 20B ÷ 86,400 ≈ 230,000 events/s (peak ~700,000)
Bandwidth: 230,000 × 1 KB ≈ 230 MB/s ≈ 1.8 Gbps (peak ~5.5 Gbps)
Raw buffer: 20 TB/day × 3 days = 60 TB × 3 replication = 180 TB in the log
Columnar: 20 TB/day ÷ 10 = 2 TB/day ≈ 730 TB/year (× 2 replicas ≈ 1.5 PB)
Brokers: peak 700 MB/s × 3 replication = 2.1 GB/s of disk writes
÷ ~100 MB/s per broker ≈ 20+ brokersConclusion: this is a write-heavy, append-only pipeline. Put a stateless ingestion tier in front that batches into a Kafka-style log. Process with stream processing, and land the results in a columnar warehouse. Never put a row-oriented OLTP database on the ingest path at 700,000 inserts a second.
Common mistakes
- Storing media in a relational database. Bytes belong in object storage. The database holds the metadata.
- Reading connection counts as a bandwidth problem. 30 million connections is a memory and connection-handling problem.
- Using one price for every byte. Egress is priced per GB, and the CDN rate changes the answer by a large factor.
Check yourself
1. In the photo app, why are uploads not the bottleneck? Peak uploads are about 175 a second. Peak views are about 170,000 a second, so the view path is the problem.
2. Why is bandwidth irrelevant in the chat problem? About 18 MB/s is trivial for modern networks. The hard parts are the connection count and the write rate.
Key takeaways
- Start each problem with the requests per day, then the peak, then storage and egress.
- Media belongs in object storage behind a CDN. Metadata belongs in a database.
- Persistent connections are a per-server memory limit, not a bandwidth limit.
- An append-only pipeline needs a log and batching, not a row-by-row OLTP write path.
Further learning
Napkin Math (Simon Eskildsen)Techniques and numbers for estimating system's performance from first-principles - sirupsen/napkin-mathGitHub
Back-of-the-envelope estimation (ByteByteGo)Ace Every Stage of Your Next Technical InterviewByteByteGo
Related
The estimation chain
The five steps that turn users and behavior into queries per second, storage, bandwidth and server count, with the multipliers you should say out loud.
Case study: chat system
Design a WhatsApp or Slack style messaging system. Connection gateways, per-conversation ordering, wide-column storage and large-channel fan-out are the parts that matter.
Object storage
Store files and media in S3-style object stores. Keep bytes out of your app servers and databases, and design uploads, metadata and costs around that split.