Non-Functional Requirements, Quantified
Turn 'scalable and reliable' into quantified, testable targets (p99, nines, QPS) and name the design lever each one forces.
NFRs are where the architecture is decided
Functional requirements say what the system does; non-functional requirements (NFRs) say how well it must do it, and they are where most of the architecture is actually decided. The trap is that NFRs are easy to fake. "The system should be scalable and reliable" is filler: it is true of every system and changes no decision. A real NFR is quantified and testable. Compare "the feed should be fast" with "p99 feed load latency under 200ms." Only the second one tells you whether you need a cache, and only the second one can be verified against a dashboard.
Sort these candidate NFRs: which could you put on a dashboard and alert on, and which are filler that changes no decision?
The rule: every NFR must be a number you could put on a Grafana panel and alert on. That means percentiles, not averages (p99, not "average latency"), because tail latency is what users feel and averages hide it. It means specific availability targets (99.99%, which is about 52 minutes of downtime per year, versus 99.9% which is about 8.7 hours) because the extra nine changes whether you need multi-region failover. It means concrete scale (100M DAU, 50k peak QPS) because that is what forces sharding.
The categories worth walking every time
- Scalability: target DAU and peak QPS. Lever: horizontal sharding, stateless services behind a load balancer.
- Latency: p99 targets, split by read and write path. Lever: caching and CDN for reads, async processing for writes.
- Availability: the number of nines. Lever: replication, multi-region, no single points of failure.
- Durability: can you ever lose committed data? Lever: replication factor, write-ahead logs, quorum writes.
- Consistency: strong or eventual, and where. Lever: this is your CAP/PACELC stance.
Take a consistency stance out loud
The consistency stance is the one interviewers probe hardest. For a feed, take an explicit position: "I favor availability over strong consistency. If a follower sees a new tweet a few seconds late, that is fine; if the feed is unavailable, that is not. So per PACELC, I choose AP during a partition and, even without a partition, I trade consistency for latency by serving from replicas and caches." That is a defensible stance with a reason, which is what scores. Saying "it should be consistent and available" fails, because CAP says you cannot have both under a partition and the interviewer will make you pick.
Split read-path and write-path SLAs, because they are genuinely different systems. The read path (loading a feed) must be fast and is cacheable, so p99 under 200ms is reasonable. The write path (posting a tweet) must be durable and ordered but can be slower, so "the write is acknowledged in under 500ms and the tweet is durably stored" is the goal, with fan-out happening asynchronously afterward. Conflating them leads you to either make writes too slow or reads not durable enough.
NFR -> forces
------------------------------------------------
p99 read < 200ms -> Redis cache + CDN
100M DAU, ~50k peak QPS -> shard datastore, stateless app tier
99.99% availability -> multi-region replication, failover
No data loss on ack -> quorum/replicated writes, WAL
Feed eventual consistency OK -> AP stance, async fan-out via Kafka
Interview nuance: When you state an NFR, immediately name the design lever it forces. That single habit, NFR then lever, is what separates a candidate who lists requirements from one who uses them to drive architecture. If an NFR does not force a lever, it is filler and you should drop it.
Recap: Write NFRs as quantified, testable numbers (percentiles, nines, QPS), take an explicit consistency stance, split read and write SLAs, and tie each NFR to the specific design lever it forces.
Apply
Your turn
The task this lesson builds to.
List 4-5 non-functional requirements for a 100M-DAU feed system as quantified, testable statements and name the design lever each one forces.
Think about
- Which NFRs actually change your architecture, and which are generic filler?
- What is your explicit CAP/PACELC stance for this system and why?
- How do read-path and write-path SLAs differ here?
Practice
Make it stick
A second problem on the same idea, so it survives past today.
Write 4-5 quantified non-functional requirements for a payment processing system like Stripe handling 5,000 transactions per second, and the lever each forces. Note where your consistency stance differs from a social feed and why.
Think about
- Which failure is catastrophic here: stale data, lost data, or a double charge? How does that invert the feed's priorities?
- What makes retries dangerous in a payment API, and which mechanism makes them safe?
- Why might you choose active-passive failover over active-active for money movement?