Skip to main content
Articles/Capacity Planning/capacity-estimation-guide
Series: System Design Interview Prepβ€’Part 4 of 24
Scenario Article

The Role of Data in Precise Capacity Estimations for System Design

Reference Numbers to Memorize

Abstract Algorithmsβ€’Mar 9, 2026
XLinkedInReddit
πŸ’‘ Executive Summary

Capacity estimation is the skill of back-of-the-envelope math that tells you whether your system design will survive its traffic before you write a line of code.

🎯 System Scenario & Requirements

System Goal

Capacity estimation is the skill of back-of-the-envelope math that tells you whether your system design will survive its traffic before you write a line of code.

Actors & Components

  • Application or API tier
  • Core service under design
  • Operator or SRE observer

Functional Requirements

  • TLDR: Capacity estimation is the skill of back-of-the-envelope math that tells you whether your system design will survive its traffic before you write a line of code.
  • Four numbers do most of the work: DAU, QPS, Storage/day, and Bandwidth/day .
  • Step 1 β€” DAU to QPS $$\text{QPS} = \frac{\text{DAU} \times \text{requests per user per day}}{86400 \text{ seconds}}$$ Example β€” Twitter-scale: - 100M DAU, each user generates 10 requests/day (timelines, searches, posts).

Constraints & Assumptions

⚑ Execution Stages & Decision Trace

1

Stage 1 β€” Estimation Decision Flow

Action / Decision:

Use this decision tree to structure any capacity estimation from scratch.

Component Behavior:

Start with DAU and follow the branches to determine what infrastructure tier your system actually needs β€” single server, horizontally scaled, or fully distributed.

Observable Output: The key decision point is the scale tier .
Read Full Stage in Deep Dive ↓
πŸ“–

Deep Dive

Detailed Architectural Analysis

Scenario context

Capacity estimation is the skill of back-of-the-envelope math that tells you whether your system design will survive its traffic before you write a line of code. Four numbers do most of the work: DAU, QPS, Storage/day, and Bandwidth/day.

flowchart LR
    DAU["Daily Active Users (e.g., 10M)"] --> QPS["Convert to QPS (requests/sec)"]
    QPS --> Storage["Storage/day (data written)"]
    QPS --> Ba…

This walkthrough focuses on **Reference Numbers to Memorize**.

Before making a design choice, clarify:

- 

**Concepts in play:** system-design-hld-architectures, caching, jvm-internals-and-garbage-collection, consistency-replication

## Stage 1 β€” Estimation Decision Flow

- Use this decision tree to structure any capacity estimation from scratch.
- Start with DAU and follow the branches to determine what infrastructure tier your system actually needs β€” single server, horizontally scaled, or fully distributed.
- The key decision point is the scale tier .
- A system handling 100 RPS and one handling 100,000 RPS require fundamentally different architectures β€” not just bigger servers, but different data stores, caching strategies, and deployment models.

*Applies [**system-design-hld-architectures**](/concept/system-design-hld-architectures) to the decision above.*

```mermaid
flowchart TD
    Start[Start Estimation] --> DAU[Estimate DAU]
    DAU --> RW[Estimate Read/Write Ratio]
    RW --> QPS[Calculate QPS DAU  actions / 86400]
    QPS --> Peak[Multiply by 2-3x for peak]
    Peak --> Storage[Calculate Storage/day write QPS  record size  86400]
    Storage --> BW[Calculate Bandwidth read QPS  response size]
    BW --> Scale{Scale tier?}
    Scale -->|< 1000 RPS| Small[Single server PostgreSQL]
    Scale -->|1k-100k RPS| Med[App servers + cache + sharding]
    Scale -->|> 100k RPS| Large[Distributed system CDN + microservices]

Observable outcome: A system handling 100 RPS and one handling 100,000 RPS require fundamentally different architectures β€” not just bigger servers, but different data stores, caching strategies, and deployment models.

Stage 2 β€” Real-World Application: Capacity Estimation Across Scale Tiers

  • The best way to internalize the four-step pipeline is to run it on systems you already use every day.
  • Here are three scenarios at very different scales that demonstrate how the numbers drive architecture decisions.
  • Twitter/X-Scale Feed - DAU: 400M users.
  • Each user reads ~10 timeline requests/day; each user writes ~0.1 tweets/day.

Observable outcome: Each user reads ~10 timeline requests/day; each user writes ~0.1 tweets/day.

Stage 3 β€” Deep Dive: Worked Example β€” Design a Pastebin

    • Write QPS = (1M Γ— 1 paste/day) / 86400 β‰ˆ 12 writes/sec - Read QPS = 12 Γ— 10 = 120 reads/sec - Storage: 12 writes/sec Γ— 10 KB Γ— 86400 = ~10 GB/day β†’ 10 TB over 3 years.
    • Read bandwidth: 120 reads/sec Γ— 10 KB = 1.2 MB/sec β†’ no CDN needed at this scale.
  • What this tells you: - A single PostgreSQL can comfortably handle sub-1000 writes/sec.
    • Storage backend should be durable object storage to handle 10 TB over 3 years.

Observable outcome: - Storage backend should be durable object storage to handle 10 TB over 3 years.

Stage 4 β€” Practical: Interview Estimation Template

  • In a system design interview, the interviewer is watching whether you have a structured process β€” not whether you arrive at the exact right number.
  • Here is a reusable five-step template you can follow verbatim: Quick Reference Decision Rules Two threshold rules that short-circuit most infrastructure architecture debates: - If storage 1 TB/day β†’ use object storage (…
  • A relational database is not designed for multi-terabyte raw ingest at sustained write rates.
    • If read bandwidth 1 GB/s β†’ put a CDN in front.
Step 1 β€” State assumptions:
  - DAU: X million
  - Read:Write ratio: X:1
  - Average object size: X KB/MB

Step 2 β€” Calculate QPS:
  - Write QPS = DAU Γ— writes_per_user / 86400
  - Read QPS = Write QPS Γ— read_write_ratio
  - Peak QPS = Average QPS Γ— 3

Step 3 β€” Calculate Storage:
  - Storage/day = write QPS Γ— record_size Γ— 86400
  - 5-year storage = storage/day Γ— 365 Γ— 5
  - Account for replication: Γ— 3

Step 4 β€” Calculate Bandwidth:
  - Read bandwidth = read QPS Γ— response_size
  - CDN threshold: > 1 GB/s read bandwidth

Step 5 β€” Determine scale tier:
  - < 1k RPS: single server
  - 1k-100k RPS: horizontal scaling + cache
  - > 100k RPS: distributed + CDN

Observable outcome: - If read bandwidth 1 GB/s β†’ put a CDN in front.

Stage 5 β€” Spring Boot + JMeter: From Capacity Estimates to Measured Throughput

  • Spring Boot is the standard Java framework for building the HTTP services whose QPS, storage, and latency you estimate.
  • Apache JMeter is the open-source load testing tool that validates those estimates against a running service β€” generating synthetic traffic at the calculated peak load and measuring actual throughput and p95 latency.
  • The workflow: estimate peak QPS on paper β†’ implement the endpoint β†’ run a JMeter test plan at estimated load β†’ compare results against your SLA targets.
  • Instrument the endpoint to compare live p95/p99 against your paper estimate: JMeter test plan β€” simulating estimated peak load: Capacity estimate vs.
// Close the estimation feedback loop: @Timed captures actual latency from live traffic
// so you can compare measured p95 against the "p95 < 50ms at 11,600 RPS" estimate.

@GetMapping("/api/users/{id}")
@Timed(value = "user.lookup.latency",
       percentiles = {0.50, 0.95, 0.99},    // exported to Prometheus/Grafana/Actuator
       description = "Cache-aside: Redis ~0.5ms hit, DB ~5ms miss")
public ResponseEntity<UserDto> getUser(@PathVariable String id) {
    // L1 β€” Redis: serves ~90%+ of requests at sub-millisecond cost
    UserDto cached = cache.opsForValue().get("user:" + id);
    if (cached != null) return ResponseEntity.ok(cached);

    // L2 β€” PostgreSQL: cache miss, fills cache for next request (5-minute TTL)
    return userRepository.findById(id)
        .map(u -> { cache.opsForValue().set("user:" + id, u, 5, MINUTES); return ResponseEntity.ok(u); })
        .orElse(ResponseEntity.notFound().build());
}
// If Actuator shows p99 > 100ms β†’ add a read replica or extend Redis TTL
<!-- Thread Group: 1000 concurrent users, 5-minute sustained load at peak QPS -->
<!-- This maps to: 11,600 RPS Γ· 1000 users β‰ˆ 11.6 requests/sec per user -->
<ThreadGroup>
  <numThreads>1000</numThreads>         <!-- virtual users -->
  <rampTime>60</rampTime>               <!-- ramp up over 60 seconds -->
  <duration>300</duration>              <!-- hold load for 5 minutes -->

  <HTTPSamplerProxy>
    <domain>localhost</domain>
    <port>8080</port>
    <path>/api/users/${userId}</path>   <!-- CSV Data Set: randomised user IDs -->
    <method>GET</method>
  </HTTPSamplerProxy>

  <!-- Add Listeners: Aggregate Report, Response Time Graph, Active Threads Graph -->
</ThreadGroup>

Observable outcome: Instrument the endpoint to compare live p95/p99 against your paper estimate: JMeter test plan β€” simulating estimated peak load: Capacity estimate vs.

Stage 6 β€” Key Lessons from Back-of-Envelope Estimation

  • Five lessons that separate engineers who nail capacity estimation from those who overcomplicate it: 1.
  • The goal is the scale tier, not the exact number.
  • Whether your estimate lands at 80,000 RPS or 120,000 RPS doesn't change the architecture decision: both require distributed infrastructure with a load balancer and horizontal scaling.
  • A 10Γ— error is usually tolerable; a 100Γ— error is a design problem.
flowchart TD
    Start[Start: State Assumptions] --> DAU[DAU  actions/user]
    DAU --> QPS[Avg Write QPS = DAU  writes / 86400]
    QPS --> Peak[Peak QPS = Avg  2-3x]
    Peak --> RQPS[Read QPS = Write QPS  read: write ratio]
    RQPS --> Storage[Storage/day = write QPS  record size  86400]
    RQPS --> BW[Bandwidth/day = read QPS  response size]
    Storage --> Scale{Scale tier?}
    BW --> CDN{BW > 1 GB/s?}
    CDN -->|Yes| AddCDN[Add CDN layer]
    CDN -->|No| NoCDN[Direct serving OK]
    Scale -->|under 1k RPS| Small[Single server]
    Scale -->|1k-100k RPS| Med[Horizontal + cache]
    Scale -->|over 100k RPS| Large[Distributed + CDN]

Observable outcome: A 10Γ— error is usually tolerable; a 100Γ— error is a design problem.

End-to-end outcome

The Role of Data in Precise Capacity Estimations for System Design

Alternatives considered

The source focuses on one primary design. A second architecture is not compared, so no alternative is invented here.

Failure and degraded modes

Trade-offs & Failure Modes: Trade-offs, Failure Modes & Decision Guide: Estimation Mistakes

  • Detection: Trade-offs & Failure Modes: Trade-offs, Failure Modes & Decision Guide: Estimation Mistakes
  • User or operator impact: Trade-offs & Failure Modes: Trade-offs, Failure Modes & Decision Guide: Estimation Mistakes

Share this case study

Discuss architecture trade-offs and lessons with your team.

Share:XLinkedInReddit