Capacity Calculator
DAU to peak QPS, bandwidth, storage and instance count — with the multipliers that decide whether the estimate is any good.
Performance & Latency·Last reviewed · revision 1
Inputs
Payloads & retention
Serving
Runs entirely in your browser. Nothing is uploaded, stored, or sent anywhere.
Results
Traffic
Peak QPS
1,042/s
347/s average — 30,000,000 requests/day
Request mix at peak
- Reads
- 938/s
- Writes
- 104/s
- Origin reads (80% cache hit)
- 187/s
Bandwidth
- Peak egress
- 66.7 Mbps
- Egress per month
- 7.20 TB
Storage
Provisioned at 365 days retention
9.86 TB
2.19 TB raw x 3 replicas x 1.5 overhead
- New data per day
- 6.00 GB
- New data per month
- 180 GB
- New data per year
- 2.19 TB
- Writes per day
- 3,000,000
Compute
Instances at peak
4
300/s usable each
With N+1 spare
5
Storage and bandwidth use decimal (SI) units — 1 GB = 109 bytes — because that is how cloud providers bill. Instance counts assume requests are uniform and stateless; a workload with an expensive minority of requests needs its own per-endpoint pass. These are order-of-magnitude figures for a design review, not a procurement plan.
Capacity estimation is nine pieces of arithmetic on top of one number: there are 86,400 seconds in a day, so one request per user per day across a million users is about 12 QPS. The estimate's quality lives entirely in four multipliers — peak-to-average ratio, payload sizes, storage overhead, and per-instance throughput — not in the arithmetic.
How it computes
Nine formulas, all of them arithmetic you could do on a whiteboard. They are written out here so you can check the tool rather than trust it.
requests/day = DAU × requests per user per day
average QPS = requests/day ÷ 86,400
peak QPS = average QPS × peak multiplier
write QPS = peak QPS × write share
read QPS = peak QPS − write QPS
origin reads = read QPS × (1 − cache hit rate)
peak egress = peak QPS × response bytes × 8 (bits/second)
new data/day = requests/day × write share × stored bytes per write
provisioned = new data/day × retention × replicas × overhead
instances = ⌈ peak QPS ÷ (RPS per instance × target utilisation) ⌉There are 86,400 seconds in a day. That single number does most of the work in a capacity conversation, and it is the one worth memorising: one request per user per day, for one million users, is about 12 QPS.
Choosing the inputs
The output is only as good as the multipliers, and four of them are where estimates go wrong.
Peak-to-average multiplier
Average QPS is a fiction — nobody experiences the average. You provision for the peak.
| Traffic shape | Multiplier |
|---|---|
| Always-on telemetry, machine-generated | 1.2–1.5x |
| Global consumer product, spread across timezones | 2–3x |
| Single-country consumer product | 3–5x |
| B2B tool used during office hours | 4–6x |
| Event-driven — ticket sales, drops, live sport | 20–100x |
The last row is why event-driven products need queues and admission control rather than more instances. You cannot buy your way to a 50x spike.
Response and record sizes
| Payload | Typical |
|---|---|
| JSON API response, single entity | 2–10 KB |
| JSON list response, 20 items | 20–80 KB |
| HTML document | 30–100 KB |
| Web page, all assets, first visit | 1–3 MB |
| Mobile image, compressed | 100–400 KB |
| Log line, structured | 0.5–2 KB |
| Metric data point | 20–100 B |
The stored bytes per write field is deliberately separate from the response size. A 40 KB response assembled from six tables might durably store 300 bytes. Conflating the two is the most common way storage estimates come out an order of magnitude high.
Storage overhead
The raw record size is never what you provision. Indexes, write-ahead logs, free-space targets, fragmentation and compaction headroom all sit on top.
| Store | Overhead multiplier |
|---|---|
| PostgreSQL, moderately indexed | 1.4–2.0x |
| PostgreSQL, heavily indexed | 2.0–3.0x |
| Cassandra / RocksDB (compaction headroom) | 1.5–2.0x |
| Columnar with compression | 0.1–0.4x (it shrinks) |
| Object storage | ~1.0x |
Replication multiplies on top of that, and it is separate: three replicas of a 2x-overhead Postgres dataset is 6x the raw bytes before backups. Backups are extra again.
Requests per second per instance
The default of 500 assumes a modest, mostly I/O-bound service on a few cores. Reality varies by two orders of magnitude, so measure yours rather than accepting the default:
| Workload | RPS per instance |
|---|---|
| Static content from a reverse proxy | 20,000–100,000 |
| Simple JSON API, one cached read | 2,000–10,000 |
| Typical service, 2–5 database calls | 200–1,000 |
| Heavy computation or serialisation | 20–200 |
| LLM-backed endpoint | 1–20 |
Then derate. Target utilisation of 60–70% is not waste — it is the space that absorbs GC pauses, deploy rollovers, a noisy neighbour and the loss of one availability zone. A fleet sized to 95% utilisation is a fleet with no capacity to fail in.
Where these estimates are wrong
Be honest about this in the design review rather than after the incident.
Uniform requests. The tool assumes every request costs the same. Real systems have an expensive minority — a search, a report, an export — that consumes most of the capacity while being a rounding error in the count. If one endpoint is 5% of traffic and 60% of CPU, size that endpoint separately.
Independent users. Real traffic is correlated. A push notification, a marketing email, a cron, or an outage recovery synchronises users into a spike no multiplier predicted. See thundering herd.
No retries. Under stress, every layer retries, and the load on a struggling dependency can be several times the nominal figure. Capacity plans that ignore retry amplification understate the failure case badly.
Steady-state growth. Retention is linear here. Products that succeed do not grow linearly, and products that pivot orphan the data model entirely.
Cache hit rate is an input, not a fact. It is measured, and it degrades — under a cold start, after a deploy, during a key-space change. Run the numbers again at a 0% hit rate and check that the origin survives. If it does not, the cache is load-bearing and needs to be treated as a dependency with its own availability target.
Using it in a design review
The value is not the number. It is which order of magnitude you land in, because that decides the shape:
| Peak QPS | What it implies |
|---|---|
| < 100 | One instance and a managed database. Anything more is over-engineering. |
| 100 – 1,000 | A handful of instances, a read replica, a cache. Still boring. |
| 1,000 – 10,000 | Connection pooling matters, caching is load-bearing, a queue appears. |
| 10,000 – 100,000 | Partitioning, regional distribution, and capacity as a standing concern. |
| > 100,000 | Purpose-built. Every generic answer stops applying. |
The same applies to storage: 500 GB is a laptop, 50 TB is a cluster decision, 5 PB is a company strategy.
Pair the output with the data store selection matrix once you know the volumes, and with the SLO calculator once you know what availability you owe on top of it.
Sources
- Site Reliability Engineering — Chapter 18, Software Engineering in SRE (capacity planning) — Google SRE (verified )
- Using load shedding to avoid overload — Amazon Builders' Library (verified )
Frequently asked
How do you convert daily active users to QPS?
Multiply daily active users by requests per user per day, then divide by 86,400 seconds. That gives average QPS. Multiply by a peak-to-average ratio — typically 2 to 3 for a global consumer product, 3 to 5 for a single-country one, and 4 to 6 for a B2B tool used in office hours — to get the figure you actually provision for.
What peak-to-average traffic ratio should you assume?
1.2 to 1.5 for machine-generated telemetry, 2 to 3 for a globally distributed consumer product, 3 to 5 for a single-timezone consumer product, 4 to 6 for B2B software used during office hours, and 20 to 100 for event-driven traffic such as ticket sales or live sport. The last case cannot be solved by provisioning; it needs queueing and admission control.
How much storage overhead should you budget above raw data size?
For PostgreSQL, 1.4 to 2 times raw for moderate indexing and 2 to 3 times for heavy indexing. Cassandra and other LSM stores need 1.5 to 2 times for compaction headroom. Columnar stores with compression usually shrink the data to 0.1 to 0.4 times. Replication multiplies on top of that, and backups are extra again.
What target utilisation should you size a fleet to?
60 to 70 percent of peak capacity. The remaining headroom absorbs garbage collection pauses, deploy rollovers, noisy neighbours and the loss of an availability zone. A fleet sized to 95 percent utilisation has no capacity left to fail in, and the first instance loss cascades.
Why do capacity estimates usually turn out wrong?
Four assumptions: that all requests cost the same when an expensive minority dominates CPU, that users behave independently when pushes and crons synchronise them, that there are no retries when retry amplification can multiply load several times under stress, and that the cache hit rate is a fact rather than a measurement that degrades. Re-run the numbers at a zero percent cache hit rate and check the origin survives.
Is this calculator accurate enough for production planning?
It is an order-of-magnitude tool for design reviews and interviews, which is what capacity estimation is for. The value is knowing whether you are at 100 QPS or 100,000 QPS, because that decides the architecture. Actual provisioning should follow a load test against your real access pattern and data distribution.
Revision history
First publication. Nine formulas, three worked presets, and reference tables for peak multipliers, payload sizes, storage overhead and per-instance throughput.
Go deeper
- ArticleScaling to Millions: An Architecture Teardown
- ArticleCaching, Idempotency and Retries at Scale
- ArticleCost-Effective Cloud Architecture Patterns
- PathwaySystem Design Mastery
- ReferenceLatency Numbers Every Engineer Should Know — 2026
- ReferenceData Store Selection Matrix
- ToolSLO & Error Budget Calculator