Someone tells you: "Design Instagram."
Your very next thought should not be "microservices" or "Kafka". It should be a much simpler question:
How big is this thing, actually?
Because the answer changes everything. A photo app for 1,000 users runs happily on one small server with one database. The same app for 500 million users needs sharding, CDNs, replicas, queues, and a monthly bill with a lot of zeros in it.
Capacity estimation is the skill of going from "500 million users" to "okay, that's roughly 6,000 writes per second and 3 petabytes of storage" — in about two minutes, on a whiteboard, without a calculator.
Capacity estimation converts user counts into the three numbers that drive every architecture decision — QPS, storage, and bandwidth.
1. Why bother estimating at all?
It feels like busywork. It isn't. Here's what these numbers actually buy you.
| Question you can now answer | Because you estimated... |
|---|---|
| Do I need one database or a sharded cluster? | Storage size and write QPS |
| Can I cache everything in memory? | Size of the "hot" working set |
| Do I need a CDN? | Outgoing bandwidth |
| How many app servers? | Peak QPS ÷ QPS one server handles |
| Is this design affordable? | Storage + bandwidth are the two biggest cloud bills |
| Should writes be async (queued)? | Write QPS vs what the database can absorb |
In an interview, estimation is where you prove you think in systems and not just in boxes and arrows. A candidate who says "we'll need a cache" is guessing. A candidate who says "reads are 100x writes at ~60k QPS, so a cache is doing the heavy lifting here" is engineering.
2. The three numbers you always estimate
Almost every estimation boils down to these three, in this order:
QPS — Queries Per Second
How many requests hit your system every second? Split into read QPS and write QPS, because they stress completely different parts of your architecture.
Storage
How many bytes do you accumulate? Usually expressed per day and per 5 years, because storage only ever grows.
Bandwidth
How many bytes per second move in and out? Also split: ingress (uploads coming in) and egress (downloads going out). Egress is the one that costs real money.
Everything else — number of servers, cache size, shard count — is derived from these three.
3. The numbers you must memorize
You can't do fast math without a few anchors. These are the ones worth committing to memory.
3.1 Time
| Period | Exact seconds | Use this instead |
|---|---|---|
| 1 day | 86,400 | 100,000 (10⁵) |
| 1 month | 2,592,000 | 2.5 million |
| 1 year | 31,536,000 | 30 million |
The single most useful trick in all of capacity estimation:
1 day ≈ 100,000 secondsSo to go from per day to per second, just divide by 100,000 — which means chop off 5 zeros. No calculator needed.
1 million events/day → 10 per second. 100 million events/day → 1,000 per second. 1 billion events/day → 10,000 per second.
The real number is 86,400, so you overestimate by about 16%. That is completely fine — and it errs on the safe side.
3.2 Data sizes (powers of 2)
| Unit | Power of 2 | Short version | Real-world feel |
|---|---|---|---|
| KB (Kilobyte) | 2¹⁰ | 1 thousand bytes | A short text post |
| MB (Megabyte) | 2²⁰ | 1 million bytes | A photo, an MP3 |
| GB (Gigabyte) | 2³⁰ | 1 billion bytes | A movie; RAM in a laptop |
| TB (Terabyte) | 2⁴⁰ | 1 trillion bytes | A big hard drive; a mid-size DB |
| PB (Petabyte) | 2⁵⁰ | 1,000 TB | A large company's data lake |
For estimation, pretend 1 KB = 1,000 bytes (not 1,024). The 2.4% error is irrelevant, and the mental math becomes trivial: each step up is just "add three zeros."
3.3 Typical object sizes
You'll need to assume a size for "one thing". These are reasonable defaults nobody will argue with:
| Object | Assume |
|---|---|
| A tweet / short text post | ~300 bytes (with metadata: ~1 KB) |
| A user record (id, name, email, settings) | ~1 KB |
| A chat message | ~100 bytes - 1 KB |
| A URL in a URL shortener | ~500 bytes per row |
| A compressed photo | ~200 KB - 2 MB (use 1 MB) |
| A profile thumbnail | ~20 KB |
| 1 minute of 1080p video | ~50 MB |
| A log line | ~200 bytes - 1 KB |
3.4 What one machine can roughly do
| Resource | Rough capacity of one commodity server |
|---|---|
| Web/app server (simple requests) | 1,000 - 10,000 QPS |
| SQL database (reads, indexed) | ~5,000 - 10,000 QPS |
| SQL database (writes) | ~1,000 - 5,000 QPS |
| Redis / in-memory cache | ~100,000+ QPS |
| RAM on one big machine | 64 GB - 512 GB |
| Disk on one machine | a few TB |
| Network on one machine | 1 - 10 Gbps |
These are order-of-magnitude anchors, not benchmarks. Real numbers depend on query shape, indexes, hardware, and language. Their purpose is to let you say "one server can't do 500k QPS, so we need at least ~50-100 of them" — and be right about the shape of the answer.
4. The estimation recipe
Every capacity estimate follows the same five steps. Learn the sequence and you'll never freeze on a whiteboard.
State your assumptions out loud
Total users, daily active users (DAU), actions per user per day, average object size. Write them down. If an interviewer disagrees with an assumption, they'll correct you — and that's a conversation, not a failure.
Compute writes per day, then per second
writes/day = DAU x actions per user per day, then divide by 100,000.
Apply the read:write ratio
Most systems read far more than they write. Multiply write QPS by the ratio to get read QPS.
Multiply by a peak factor
Traffic isn't flat across 24 hours. Multiply average QPS by 2-3x to get peak QPS. Design for peak, not average.
Compute storage and bandwidth
storage/day = writes/day x object size, then project out 1 year and 5 years.
bandwidth = QPS x object size.
Round aggressively at every step. 86,400 → 100,000. 365 → 400. 7.3 → 10. You are hunting for the magnitude. Precision here is a trap that costs you time and buys you nothing.
5. Understanding DAU, actions, and the read:write ratio
Three assumptions do most of the work. Getting a feel for them is most of the skill.
5.1 Total users vs Daily Active Users
Nobody uses an app every day. DAU is typically 10-30% of registered users.
1 billion registered users → assume ~300 million DAU
Always estimate from DAU. Estimating from total registered users overshoots by 3-10x.
5.2 Actions per user per day
How many times does one active user do the thing?
| System | Writes / user / day | Reads / user / day |
|---|---|---|
| Twitter / X | ~2 tweets | ~200 timeline views |
| ~0.1 posts | ~100 photo views | |
| ~50 messages | ~50 messages received | |
| YouTube | ~0.001 uploads | ~5 video views |
| URL shortener | 1 create | ~100 redirects |
5.3 The read:write ratio
This is the number that shapes your entire architecture.
| Ratio | Type of system | What the architecture needs |
|---|---|---|
| 100:1 or higher | Read-heavy (Twitter, YouTube, news, URL shorteners) | Caching, read replicas, CDN |
| ~1:1 | Balanced (chat, messaging) | Fast writes and fast reads; partitioning |
| Write-heavy (1:10) | Logging, metrics, IoT sensors, analytics ingestion | Queues, batching, LSM-tree / time-series DBs |
Why the ratio matters so much: reads can be cached, replicated, and served from the edge — they scale outward almost for free. Writes must reach the source of truth, must be durable, and must stay consistent — they scale hard.
So a 100:1 read-heavy system with 60,000 QPS is a caching problem. A write-heavy system at the same QPS is a sharding and durability problem. Same number, totally different design.
6. Worked example #1: Twitter / X
Let's do a full estimate, slowly.
6.1 Assumptions
| Assumption | Value |
|---|---|
| Daily active users | 300 million |
| Tweets per user per day | 2 |
| Timeline reads per user per day | 200 |
| Size of one tweet (text + metadata) | 1 KB |
| Percentage of tweets with media | 10%, at 1 MB each |
6.2 Write QPS
300,000,000 users x 2 tweets = 600,000,000 tweets/day
Now divide by 100,000 (chop 5 zeros):
600,000,000 ÷ 100,000 = 6,000 tweets/second
Apply a 2x peak factor:
Peak write QPS ≈ 12,000/second
6.3 Read QPS
300,000,000 x 200 = 60,000,000,000 reads/day
60,000,000,000 ÷ 100,000 = 600,000 reads/second
Peak: ~1,200,000 reads/second
Stop and look at those two numbers. 6,000 writes/sec vs 600,000 reads/sec — a 100:1 ratio.
This single observation tells you the whole architecture. You cannot serve 600k reads/second from a database. That number demands aggressive caching and precomputed timelines (fan-out on write). You just derived the core design decision from arithmetic alone.
6.4 Storage
Text:
600,000,000 tweets/day x 1 KB = 600 GB/day
Media (10% of tweets, 1 MB each):
60,000,000 x 1 MB = 60 TB/day
Total ≈ 60.6 TB/day, which is basically 60 TB — the text is a rounding error next to the images.
Over 5 years:
60 TB/day x 365 x 5 ≈ 110 PB
Notice what happened: media is 100x bigger than text. This is why real systems store media in object storage (S3, blob storage) behind a CDN, and keep only the URL in the database. Your database stays small and fast; the bytes live somewhere cheap.
You discovered that architectural rule purely from the numbers.
6.5 Bandwidth
Egress (what you serve to users) — assume a timeline read returns ~10 tweets and some images, roughly 100 KB per read:
600,000 reads/sec x 100 KB = 60 GB/second
That's about 480 Gbps.
One server has maybe 10 Gbps of network. 480 Gbps means you'd need ~50 servers just to push bytes — before doing any actual work.
Conclusion: a CDN is not optional here. Static media must be served from edge locations, not your origin servers.
Twitter — final numbers:
Write QPS 6,000/s (peak 12,000/s) Read QPS 600,000/s (peak 1,200,000/s) Ratio 100 : 1 Storage 60 TB/day → ~110 PB over 5 years Egress 60 GB/s ≈ 480 Gbps
7. Worked example #2: URL shortener (like bit.ly)
A smaller, cleaner example — and an extremely common interview question.
7.1 Assumptions
| Assumption | Value |
|---|---|
| New URLs created | 100 million / month |
| Read:write ratio | 100:1 |
| Size of one row (short code, long URL, metadata) | 500 bytes |
| Retention | 5 years |
7.2 QPS
100 million/month → per day: 100,000,000 ÷ 30 ≈ 3,300,000/day
Per second: 3,300,000 ÷ 100,000 ≈ 33 writes/second
Reads at 100:1: 3,300 reads/second
33 writes per second is nothing. A single modest database handles that without breaking a sweat. 3,300 reads/second is also very manageable, especially with a cache.
This is a genuinely important result: a URL shortener does not need a huge distributed system. The interesting problems are short-code generation without collisions and redirect latency — not scale. Estimation just saved you from over-engineering.
7.3 Storage
3,300,000 URLs/day x 500 bytes ≈ 1.65 GB/day
Over 5 years:
1.65 GB x 365 x 5 ≈ 3 TB
3 TB fits comfortably on a single machine's disk. No sharding required — though you'd still replicate for availability.
7.4 Bandwidth
Egress: 3,300 reads/sec x 500 bytes ≈ 1.65 MB/second
Trivial. A redirect is just an HTTP 301 with a header — tiny.
Compare the two examples side by side. Twitter: 600k QPS, 110 PB, 480 Gbps. URL shortener: 3.3k QPS, 3 TB, 1.65 MB/s. Both are "web apps with a database", but they live in completely different universes.
That gap is precisely what capacity estimation exists to reveal.
URL shortener — final numbers:
Write QPS 33/s Read QPS 3,300/s Storage 1.65 GB/day → ~3 TB over 5 years Egress 1.65 MB/s Verdict one database + one cache is enough
8. From numbers to servers
Once you have QPS and storage, server counts fall out by division.
8.1 App servers
servers = peak QPS ÷ QPS per server
For Twitter's 1.2M peak reads/sec, with a cache-backed server handling ~5,000 QPS:
1,200,000 ÷ 5,000 = 240 servers
Then add headroom for failures and deploys — call it 300+.
8.2 Cache sizing (the 80/20 rule)
Not all data is hot. The standard assumption: 20% of data serves 80% of requests.
For Twitter, if a day's text is 600 GB, cache the hot 20%:
600 GB x 0.2 = 120 GB of cache
At ~64 GB of usable RAM per cache node, that's ~2-4 Redis nodes (plus replicas).
8.3 Database shards
shards = total storage ÷ storage per node, and also shards = write QPS ÷ write QPS per node
Take the larger of the two. Storage can force sharding even when QPS wouldn't, and vice versa.
Two independent reasons to shard: you ran out of disk, or you ran out of write throughput. Always check both — candidates usually check only one.
9. Common mistakes
| Mistake | Why it hurts | Fix |
|---|---|---|
| Estimating from total users, not DAU | Overshoots by 3-10x, leads to wild over-engineering | Always convert to DAU first (10-30%) |
| Designing for average QPS | System collapses at peak hour | Multiply by a 2-3x peak factor |
| Forgetting the read:write split | You miss the single biggest architectural signal | Always compute both separately |
| Ignoring replication in storage math | Real storage is 3x your estimate | Multiply final storage by replication factor (usually 3) |
| Chasing exact numbers | Burns interview time, adds zero value | Round hard; magnitude is the goal |
| Silent assumptions | Interviewer can't follow or correct you | Say every assumption out loud, write it down |
| Forgetting metadata and indexes | Real DB size is often 2x raw data | Add a rough overhead multiplier |
| Treating media like text | Off by 1000x — media dominates everything | Separate media into its own line item |
The replication trap is the most commonly missed one. You calculate 3 TB and confidently say "fits on one disk." But with a replication factor of 3, it's 9 TB. Add indexes and it's ~15 TB. Add backups and retention and it grows again.
Rule of thumb: your real storage bill is 3-5x your raw data estimate.
Summary
- Capacity estimation turns "N users" into QPS, storage, and bandwidth — the three numbers that drive architecture.
- Use DAU, not total users. DAU is typically 10-30% of registered users.
- 1 day ≈ 100,000 seconds — divide by it to convert per-day into per-second by chopping five zeros.
- Always split reads from writes. The ratio tells you whether you have a caching problem or a sharding problem.
- Multiply by a 2-3x peak factor; design for the busy hour, not the average.
- Real storage is 3-5x raw data once replication and indexes are counted.
- Media dominates text by ~1000x — which is why object storage and CDNs exist.
- Round hard. Order of magnitude is the goal, and stating assumptions out loud is half the value.