System design estimation is a way to turn an ambiguous product description into approximate traffic, storage, bandwidth, and capacity requirements. The goal is not to predict an exact production number. It is to expose the order of magnitude, make assumptions visible, and identify which part of the design deserves attention first.
A useful estimate follows a repeatable sequence: define the workload, calculate average and peak requests per second, split reads from writes, estimate data growth, calculate network throughput, and translate the results into design choices. The arithmetic should be simple enough to explain aloud and detailed enough for another engineer to challenge.
Treat every number in the worked examples as an explicit hypothetical input, not a benchmark or a universal industry default. Replace assumptions with measured product analytics, load tests, payload samples, and retention requirements when sizing a real system.
The estimation method: assumptions before formulas#
Start by describing what the system does. “A social feed” is not a workload; “two million daily active users each request twenty feed pages and publish half a post per day on average” is a workload you can calculate.
Write down the assumptions before doing arithmetic:
- Users and activity: daily active users (DAU), actions per user, and whether actions happen evenly or in bursts.
- Operation mix: reads, writes, uploads, downloads, background jobs, and internal fan-out.
- Payload sizes: average request, response, record, and file sizes. Keep ingress and egress separate.
- Retention: how long records, events, files, and derived data remain available.
- Traffic shape: observed peak-to-average ratio, seasonal events, regional time zones, and retry behavior.
- Capacity target: the utilization or headroom the system should retain during normal and degraded operation.
Ask which values are known, which are estimates, and which are deliberately conservative. If a prompt does not provide a value, choose a round assumption, say why it is plausible for the scenario, and show how the result changes if it is wrong. In an interview, this is part of the answer—not a detour before the answer.
The conversions worth keeping close#
A day contains 86,400 seconds. For quick mental arithmetic, 100,000 seconds is a convenient approximation, but use 86,400 when showing a worked calculation. The approximation makes the result about 13.6% lower than the exact division, so it is useful for a first pass, not a substitute for checking a decision near a capacity boundary.
| Time interval | Seconds |
|---|---|
| 1 day | 86,400 |
| 30-day month | 2,592,000 |
| 365-day year | 31,536,000 |
For traffic, remember the order of magnitude: one million requests per day is 1,000,000 ÷ 86,400 = 11.57 requests per second, or roughly 12 average requests per second. Ten million per day is about 116/s; one hundred million per day is about 1,157/s.
Be precise about data units. Decimal units use powers of 10: 1 MB = 1,000,000 bytes and 1 GB = 1,000,000,000 bytes. Binary units use powers of 2: 1 KiB = 1,024 bytes, 1 MiB = 1,048,576 bytes, and 1 GiB = 1,073,741,824 bytes. NIST documents the distinction between SI and IEC binary prefixes. NIST: Definitions of the SI units — binary prefixes
Use one convention throughout a calculation. In the examples below, storage totals use decimal GB and TB; file sizes use MiB where binary units are more natural. State the convention rather than switching between MB and MiB as if they were identical.
Core formulas for system design estimation#
These formulas provide a starting model. They do not capture every system cost, but they expose the main quantities that influence an initial architecture.
Average and peak request rate#
requests_per_day = DAU × requests_per_user_per_day
average_RPS = requests_per_day ÷ 86,400
peak_RPS = average_RPS × peak_to_average_factor
RPS means requests per second. QPS means queries per second; teams sometimes use the terms interchangeably, but define whether a “request” is an external API call, a database query, or an internal operation. One external request can fan out into several internal calls.
Do not assume one peak factor fits every product. Calculate it from observed time-bucketed traffic when possible: peak interval rate divided by the average rate for the same interval definition. If no telemetry exists, state a scenario assumption and test alternatives. A factor of 3 in an example means “we are modeling a peak three times the average,” not “all systems peak at 3×.”
Calculate read and write rates separately. A read-heavy product may need to serve a large volume of repeated data, while a write-heavy product may need sustained ingestion, ordering, durability, or downstream processing. A combined RPS figure can hide the real constraint.
Storage growth#
new_data_per_day = writes_per_day × average_record_size
logical_storage = new_data_per_day × retention_days
physical_storage = logical_storage × copy_factor
Add indexes, metadata, compaction space, snapshots, backups, and derived data separately. A copy factor is a simplified planning input, not a universal statement about how a managed database or object store implements durability. Compression also changes the stored size; estimate it from representative data rather than assuming a fixed saving.
Network bandwidth#
bytes_per_second = requests_per_second × average_payload_bytes
bits_per_second = bytes_per_second × 8
Calculate ingress and egress independently. Use the relevant request or response size for each path. Add protocol overhead, encryption, retries, fan-out, and retransmission where they materially affect the estimate. For large files, a small request count can still produce substantial bandwidth.
Server count#
required_instances = ceil(peak_RPS ÷ sustainable_RPS_per_instance)
If the capacity target is below full utilization, use ceil(peak_RPS ÷ (sustainable_RPS_per_instance × target_utilization)). The per-instance rate must come from a representative load test or a defensible capacity measurement for the actual workload, software, instance type, and latency target. Do not copy a generic “requests per server” number into a design and present it as fact.
Worked example 1: a read-heavy feed#
Assume a feed service has 2 million daily active users. Each user loads twenty feed pages per day and creates half a post per day on average. Model peak traffic at four times the daily average. Assume each post record occupies 1,000 bytes and each feed response transfers 12,000 bytes. These are illustrative inputs.
1. Calculate reads.
reads/day = 2,000,000 users × 20 reads = 40,000,000
average read RPS = 40,000,000 ÷ 86,400 = 462.96 ≈ 463
peak read RPS = 463 × 4 ≈ 1,852
2. Calculate writes.
posts/day = 2,000,000 × 0.5 = 1,000,000
average write RPS = 1,000,000 ÷ 86,400 = 11.57 ≈ 11.6
peak write RPS = 11.57 × 4 = 46.3
The workload is roughly 40 reads for every write. That ratio does not prove a cache is required, but it tells you the read path deserves more attention than the write path in the first design pass.
3. Estimate response bandwidth.
peak egress = 1,852 responses/s × 12,000 bytes
= 22,224,000 bytes/s
≈ 22.2 MB/s ≈ 178 Mbps
This is application response payload only. It excludes transport overhead and any media served separately. If feed responses include images, model image delivery as a separate path rather than hiding it inside an average API response.
4. Estimate post storage.
new logical data/day = 1,000,000 posts × 1,000 bytes = 1 GB
one year = 1 GB/day × 365 = 365 GB
three-copy scenario = 365 GB × 3 = 1.095 TB
The 1.095 TB figure excludes indexes, metadata, backups, and media. It is not a complete database capacity plan.
Design implications: investigate caching or precomputing frequently requested feed data, and consider read replicas only if measured database read pressure justifies them. Keep writes on a simpler path initially unless ordering, fan-out, or consistency requirements change the picture. Separate media delivery from feed API responses, and validate the assumed read distribution: a highly personalized feed may not benefit from the same cache strategy as a feed of mostly shared content.
Worked example 2: a write-heavy event log#
Assume 500,000 daily active devices each emit 200 events per day. Each stored event, including its basic metadata, averages 600 bytes. Model peak ingestion at five times the average and retain events for 30 days. Use a three-copy scenario for a first storage estimate.
1. Calculate event volume and ingestion rate.
events/day = 500,000 × 200 = 100,000,000
average write RPS = 100,000,000 ÷ 86,400 = 1,157.4
peak write RPS = 1,157.4 × 5 = 5,787
2. Calculate storage.
logical data/day = 100,000,000 × 600 bytes = 60,000,000,000 bytes
= 60 GB/day
30-day logical storage = 60 GB × 30 = 1.8 TB
three-copy scenario = 1.8 TB × 3 = 5.4 TB
The 5.4 TB estimate excludes indexes, compression effects, retention gaps, backups, and temporary compaction space. If event payloads vary substantially, calculate by event class or use a measured size distribution instead of relying on one average.
3. Check ingress bandwidth.
peak ingress = 5,787 events/s × 600 bytes
= 3,472,200 bytes/s
≈ 3.47 MB/s ≈ 27.8 Mbps
The request rate is more revealing than the raw bandwidth in this example. The system must accept and durably process nearly 5,800 small events per second at the modeled peak, even though the byte rate is modest.
Design implications: consider an append-oriented ingestion path, batching, and a durable queue or log when producers and consumers need decoupling. Partitioning can distribute sustained write volume, but the partition key must avoid concentrating one hot tenant or event type on a single partition. Define ordering requirements before choosing a partition strategy: global ordering is much more restrictive than per-device or per-aggregate ordering. Use retention and compaction policies that match the actual query and audit requirements.
Worked example 3: a file upload service#
Assume 100,000 daily active users upload two files each per day. The average file is 8 MiB. Model upload peaks at eight times the average. Assume each uploaded file is downloaded three times on average, downloads peak at four times their average, and files are retained for 30 days. For a simplified capacity scenario, count three stored copies.
1. Calculate upload traffic.
uploads/day = 100,000 × 2 = 200,000
average upload RPS = 200,000 ÷ 86,400 = 2.31
peak upload RPS = 2.31 × 8 = 18.52
The request rate looks small. The payload size changes the capacity picture.
2. Calculate upload bandwidth.
peak ingress = 18.52 uploads/s × 8 MiB
≈ 155.3 MB/s ≈ 1.24 Gbps
The conversion uses 8 MiB = 8,388,608 bytes and decimal MB for the final rate. This is a payload estimate, not a provisioned network target; protocol overhead and burst shape still matter.
3. Calculate storage.
data/day = 200,000 × 8,388,608 bytes
= 1.678 TB/day (decimal)
30-day logical storage = 1.678 TB × 30 ≈ 50.33 TB
three-copy scenario = 50.33 TB × 3 ≈ 150.99 TB
4. Estimate download egress.
downloads/day = 200,000 uploads × 3 = 600,000
average download RPS = 600,000 ÷ 86,400 = 6.94
peak download RPS = 6.94 × 4 = 27.78
peak egress = 27.78 × 8 MiB ≈ 233 MB/s ≈ 1.86 Gbps
Design implications: this is a data-transfer and storage problem, not simply an API request-count problem. Consider direct-to-object-storage uploads using short-lived, scoped upload authorization so application servers do not proxy every file byte. Use asynchronous processing for malware scanning, metadata extraction, and thumbnail generation when those tasks do not need to block the upload response. A CDN may reduce origin egress for repeatedly downloaded files, subject to access control and cache policy. Confirm whether “three copies” is actually how the chosen storage service bills or exposes durability; do not multiply managed storage by three if its documented storage model already accounts for redundancy.
Compare the three estimates#
| Example | Peak primary operation | Data growth | Main pressure to investigate |
|---|---|---|---|
| Read-heavy feed | ~1,852 reads/s; ~46 writes/s | 1 GB/day logical posts | Read path, cacheability, feed fan-out |
| Write-heavy event log | ~5,787 writes/s | 60 GB/day logical events | Sustained ingestion, partitioning, retention |
| File upload service | ~18.5 uploads/s; ~27.8 downloads/s | ~1.68 TB/day logical files | Ingress/egress bandwidth and object storage |
The examples are not directly comparable capacity benchmarks: their workloads, payloads, and assumptions differ. Their purpose is to show how the same method reveals different constraints.
Sanity checks before you trust the result#
Run these checks before turning estimates into an architecture:
- Recalculate from the other direction. Multiply average RPS by 86,400 and confirm that it returns the daily request count within rounding error.
- Check units at every step. Requests/s × bytes/request gives bytes/s. Multiply by eight only when converting bytes to bits. Do not label MB/s as Mbps.
- Separate external and internal work. If one request causes five database queries or three downstream calls, estimate those operations separately.
- Check peak and average consistency. Apply a peak factor to the same time unit and traffic category. Do not multiply a peak rate by a daily count again.
- Test the assumptions. Recalculate with half and twice the assumed activity, payload size, or retention. If the design changes sharply, the assumption needs measurement.
- Keep logical and physical storage distinct. State whether the estimate includes copies, indexes, backups, compression, and derived data.
- Look for missing workload dimensions. Concurrent connections, background jobs, retries, batch windows, and hot-key skew can matter even when average RPS looks modest.
Turn estimates into design decisions#
An estimate is useful only when it changes a question or decision. Use the numbers to identify what to investigate—not to select a database or cache by formula alone.
- Caching: consider it when reads repeat, data has an acceptable freshness window, and measured origin work is expensive. A high read/write ratio is a clue, not proof that every response is cacheable.
- Replication: separate read scaling, availability, and durability requirements. Replicas add operational and consistency considerations; they are not a universal response to high RPS.
- Partitioning: investigate it when write volume, storage growth, or data ownership exceeds a single partition's tested limits. Choose a key based on access patterns and skew, not only on even-looking IDs.
- Queues and logs: use them when ingestion and processing need independent scaling, buffering, replay, or failure isolation. They add delivery semantics and operational complexity.
- CDNs and object storage: consider them when large or repeated file transfers dominate bandwidth or application-server work. Access control and cache invalidation remain part of the design.
- Capacity and headroom: use representative load tests to estimate sustainable per-instance throughput at the latency and error-rate targets that matter. Then calculate instance count with the formula above and add failure or deployment headroom explicitly.
For an interview, narrate the assumptions, show the arithmetic, identify the largest constraint, and explain what you would measure next. For a real design, record the inputs, source, confidence, and owner beside the estimate. A useful next step is to put the assumptions and capacity implications into a technical design document, where reviewers can challenge the numbers before they become infrastructure commitments.
Use the System Design Cheat Sheet as the companion reference while practicing these calculations. The cheat sheet is the primary resource for this topic; this article explains the reasoning behind the estimates and how to connect them to architectural choices.



