Putting Numbers on NFRs
Why this matters: Lesson 1 claimed an NFR without a number isn't a requirement. This lesson is how you produce the number — including when the interviewer deliberately refuses to give you one.
Key takeaway
Nobody hands you non-functional requirements. You extract them with clarifying questions, derive them with arithmetic, and defend them by naming the decision each one forces. Precision is not the goal — the right order of magnitude, stated out loud, is.
Step 1: Ask
Proactively clarify NFRs early. The three questions that unlock most designs:
- Expected user traffic — how many users, how active, how spiky?
- Expected data load — how much stored, growing how fast, kept how long?
- Expected downtime tolerance — what does an outage actually cost?
Follow-ups worth asking when they matter:
| Question | Why it matters | What the answer changes |
|---|---|---|
| Read/write ratio? | Decides where to spend complexity | Read-heavy → caching and replicas; write-heavy → sharding and queues |
| How spiky is traffic? | Peak, not average, sizes the system | Flat → autoscaling suffices; spiky → queues and pre-warmed capacity |
| Latency budget, for which operation? | Budgets differ wildly per path | Tight → colocate and cache; loose → allow async |
| Cost of a stale read here? | The consistency question from Chapter 1 | Low → eventual; high → strong, and pay for it |
| Global or single-region? | Geography sets a latency floor | Global → regional replicas, residency rules |
| Retention period? | Storage grows without bound otherwise | Sets total storage and tiering strategy |
Step 2: Derive
Four pieces of arithmetic carry most interviews. Round aggressively — you want the exponent, not the digits.
Requests per second
Average QPS = DAU * actions per user per day / 86,400 Peak QPS = Average QPS * peak factor (typically 2x to 10x)
Use 100,000 seconds per day instead of 86,400. The 15% error is irrelevant and the mental arithmetic becomes trivial.
Storage
Storage per day = writes per day * bytes per write Total storage = storage per day * retention days * replication factor
Forgetting the replication factor is the most common miss — three replicas means three times the storage bill, and cross-region makes it more.
Bandwidth
Egress = QPS * average response size
Memory for a cache
Cache size = hot data fraction * total data
The usual heuristic: 20% of the data serves 80% of requests, so caching the hot fifth captures most reads.
A worked example
"Design a photo-sharing service." No numbers given.
Assume and state:
DAU = 100 million Photos uploaded/user/day = 0.2 (1 photo every 5 days) Photo views/user/day = 50 Average photo size = 2 MB Retention = forever Replication factor = 3
Derive:
Uploads/day = 100M * 0.2 = 20 million Write QPS = 20M / 100,000 = 200 writes/sec Peak writes = 200 * 3 = 600 writes/sec Views/day = 100M * 50 = 5 billion Read QPS = 5B / 100,000 = 50,000 reads/sec Peak reads = 50,000 * 3 = 150,000 reads/sec Read/write ratio = 50,000 / 200 = 250:1 Storage/day = 20M * 2 MB = 40 TB/day With 3x replication = 120 TB/day Per year = ~44 PB/year Egress at peak = 150,000 * 2 MB = 300 GB/sec
Now read the numbers as decisions — this is the part that scores:
| Number | What it tells you | Design decision it forces |
|---|---|---|
| 250:1 read/write | Overwhelmingly read-dominated | Optimize reads hard; writes can be expensive |
| 600 peak writes/sec | Genuinely modest | A single well-tuned primary can handle metadata writes |
| 150,000 peak reads/sec | Large | Aggressive caching plus read replicas — do not serve from the primary |
| 300 GB/sec egress | The dominant cost and constraint | CDN is mandatory, not an optimization — origin must never serve photo bytes |
| 44 PB/year, growing | Unbounded storage | Object storage, not a database; tier cold photos to cheaper classes |
| 2 MB average object | Blobs, not rows | Split metadata (database) from bytes (object store) |
Step 3: Translate to requirements
Convert the arithmetic into a stated NFR table — this is what you write on the board:
| NFR | Target | Justification |
|---|---|---|
| Availability | 99.9% (43 min/month) | Photo viewing is not safety-critical; four nines isn't worth the cost |
| Read latency | p99 under 200 ms | Feed must feel instant; CDN puts bytes near users |
| Write latency | p99 under 2 s for upload ack | Users accept an upload spinner; processing is async |
| Durability | No photo ever lost | Irreplaceable user data — stronger requirement than availability |
| Scalability | 10x growth without redesign | Stateless tier, sharded metadata, object storage scales independently |
| Consistency | Eventual for feeds, strong for privacy settings | Stale like count is harmless; stale privacy setting leaks a photo |
Notice durability being ranked above availability. That is a deliberate, defensible choice for this product: a brief outage annoys users; a lost photo is unforgivable. Stating that ranking is exactly the Staff-level move from Lesson 1.
Common patterns worth having ready
Certain requirements map to well-known answers. Recognizing them fast leaves time for the interesting parts:
| Requirement | Typical answer | Because |
|---|---|---|
| Transactions, strong invariants | ACID-compliant relational database | Constraints and multi-row atomicity are what it's for |
| Large-scale data, high write volume | NoSQL (MongoDB, Cassandra) | Horizontal scale and flexible schema over join capability |
| Real-time streams and event fan-out | Kafka or Kinesis | Durable ordered log, replayable, many independent consumers |
| Large static content, global audience | Object storage + CDN | Egress and latency both solved at the edge |
| Spiky, slow, or retriable work | Queue plus workers | Absorbs bursts; decouples the interactive path |
Key takeaway
Estimation is not about precision. It is about reaching the right order of magnitude fast enough that the number can drive a decision — and then saying out loud which decision it drove.
Interview signal by level
| Level | What a strong answer sounds like |
|---|---|
| L4 | Waits for numbers, or gives requirements without any. |
| L5 | Estimates correctly: "100M DAU at 50 views each is 5 billion reads a day, about 50k QPS average." |
| Staff+ | Uses the estimate to decide: "300 GB/sec of egress makes the CDN non-negotiable and means origin never serves bytes. If my DAU assumption is 10x off, that conclusion still holds — which is why I'm comfortable committing to it now." |
Next: all of it applied to one interview, start to finish.