All chapters in this track
- 01Chapter 1: Why System Design Is Its Own Skill
- 02Chapter 2: Core Building Blocks and Vocabulary
- 03Chapter 3: Eliciting Non-Functional Requirements
- 04Chapter 4: Back-of-Envelope Capacity Estimation
- 05Chapter 5: Caching Strategies and Cache Invalidation at the Systems Level
- 06Chapter 6: Load Balancing and Horizontal Scaling
- 07Chapter 7: Database Selection, Replication, and Sharding at a Systems Level
- 08Chapter 8: Asynchronous Processing, Message Queues, and Event-Driven Design
- 09Chapter 9: API Design from a Systems Perspective: REST, gRPC, GraphQL
- 10Chapter 10: The CAP Theorem and Consistency Models in Practical Terms
- 11Chapter 11: Microservices vs. Monoliths and Drawing Service Boundaries
- 12Chapter 12: Designing for Failure: Redundancy, Failover, Graceful Degradation
- 13Chapter 13: A Repeatable Framework for Any System Design Problem
- 14Chapter 14: Worked Example: URL Shortener
- 15Chapter 15: Worked Example: Chat System
- 16Chapter 16: Worked Example: News Feed
- 17Chapter 17: Worked Example: Rate Limiter
Chapter 3 of 17
Chapter 3: Eliciting Non-Functional Requirements
Why this matters
Companion SDLC book Chapter 4 established that non-functional requirements are the more commonly neglected category — this is even more true, and more consequential, in system design specifically, where scale, latency, availability, and consistency targets are precisely the numbers that determine which architecture is even viable, let alone optimal. A system design conversation that skips eliciting these and jumps straight to drawing boxes is building on an unstated, unexamined guess.
The core non-functional dimensions to elicit
[BEGINNER]
- Scale — how many users, how many requests per second, how much data? (Chapter 4 covers turning these into concrete numbers.)
- Latency — how fast must a response be? A search-as-you-type feature has a far tighter latency budget than a nightly batch report.
- Availability — what's the acceptable downtime? "Five nines" (99.999%) allows about 5 minutes of downtime per year; "three nines" (99.9%) allows about 8.7 hours — a massive difference in what architecture is required to achieve it.
- Consistency — can the system tolerate briefly stale/inconsistent data (eventual consistency, companion Database book Chapter 9), or does it need strong consistency guarantees regardless of cost?
- Read/write ratio — is this system read-heavy (a URL shortener, a social media feed) or write-heavy (a logging/analytics ingestion pipeline)? This ratio alone eliminates or favors entire categories of architecture.
Why these questions should come before any architecture discussion
[SENIOR INSIGHT] Every one of these dimensions can independently invalidate an otherwise-reasonable architecture. A perfectly good caching strategy (Chapter 5) is the wrong answer if the system's consistency requirement can't tolerate any staleness at all. A well-designed sharding scheme (companion Database book, Chapter 11) is unnecessary, premature complexity if the actual scale requirement turns out to be far lower than assumed. This is why eliciting non-functional requirements should happen before, not after, proposing an architecture — proposing a design first and then checking whether it happens to satisfy the real requirements is backward, and risks anchoring the conversation on an architecture that has to be substantially reworked once the actual constraints are understood.
Weak process: propose an architecture immediately, then ask "does this
need to handle a lot of scale?" afterward -- risks having
to substantially rework the proposal once the answer arrives.
Strong process: "Before I sketch an architecture, I want to understand
a few things: roughly how many users, and how many
requests per second at peak? What's an acceptable
response time for the main user-facing operation? Can
we tolerate eventual consistency, or does this need to
be strongly consistent? Is this read-heavy or write-heavy?"
-- THEN propose an architecture informed by the answers.
Interpreting vague or absent answers
[IN PRACTICE] In a real interview (and often in a real early-stage project), a stakeholder or interviewer may not have precise numbers ready — "I don't know, let's say... a lot of users" is a common, realistic response. The right move isn't to demand exact numbers before proceeding, but to propose a reasonable, explicitly-stated assumption and continue, making that assumption visible so it can be corrected if wrong: "I'll assume roughly 10 million daily active users and design around that — let me know if that's significantly off." This demonstrates the same judgment a real engineer needs when working with genuinely incomplete information, which is the norm, not the exception, in real system design work.
Common mistakes
- Jumping straight to architecture without eliciting non-functional requirements first, risking a proposal that has to be substantially reworked once the actual constraints (scale, consistency, latency) become clear.
- Demanding precise numbers before proceeding at all, rather than stating a reasonable assumption and continuing — this stalls the conversation and misses a chance to demonstrate comfort working with genuinely incomplete information.
- Treating all five dimensions as equally important for every system, rather than recognizing that a specific system's dominant constraint (extreme scale for one system, strict consistency for another) should shape where the most design attention goes.
- Not revisiting an initial architecture when non-functional requirements are clarified or corrected partway through a conversation — a good design process treats new information as a reason to adapt, not as an inconvenience to route around.
Checklist: eliciting non-functional requirements effectively
- Ask about scale, latency, availability, consistency, and read/write ratio before proposing an architecture, not after.
- When precise numbers aren't available, state a reasonable, explicit assumption and continue, rather than stalling the conversation waiting for exact figures.
- Identify which dimension is likely the dominant constraint for this specific system, and let that shape where the most design attention and trade-off discussion goes.
- Stay willing to revisit and adapt an architecture as requirements are clarified or corrected during the conversation, rather than anchoring rigidly to an initial proposal.
Discussion / interview questions
-
"What non-functional requirements would you elicit before designing a new system, and why before rather than after proposing an architecture?" Strong answer: Scale, latency, availability, consistency, and read/write ratio — eliciting these first prevents proposing an architecture that has to be substantially reworked once the actual constraints are understood, since each dimension can independently invalidate an otherwise-reasonable design.
-
"An interviewer says 'let's just say it needs to handle a lot of users' when you ask about scale. How would you proceed?" Strong answer: State a reasonable, explicit assumption (e.g., "I'll design around roughly 10 million daily active users") and continue, rather than stalling for a precise number — this demonstrates comfort working with genuinely incomplete information, which is realistic and expected.
-
"Why does the read/write ratio matter so much for system design decisions?" Strong answer: It shapes which architectural patterns are even worth considering — a read-heavy system benefits enormously from caching and read replicas; a write-heavy system needs to prioritize write throughput and might favor a different database/sharding strategy entirely — getting this wrong upfront can point the whole design in the wrong direction.
-
"What would you do if, partway through a system design conversation, you learned a non-functional requirement was different from your initial assumption?" Strong answer: Treat it as new, useful information and adapt the architecture accordingly, explaining what specifically changes and why — rigidly sticking to an initial proposal despite corrected information is a worse signal than gracefully incorporating new constraints.
Chapter summary / cheat sheet
- Elicit scale, latency, availability, consistency, and read/write ratio before proposing an architecture — each can independently invalidate an otherwise-reasonable design.
- When precise numbers aren't available, state a reasonable, explicit assumption and continue, rather than stalling the conversation.
- Identify the dominant constraint for the specific system at hand, rather than treating every dimension as equally weighted.
- Stay willing to adapt an architecture as requirements are clarified or corrected — this is realistic, expected behavior, not a sign of an unstable initial design.