Skip to main content

Requirements & NFRs That Matter

Editorial

The prompt is the trap

"Design a URL shortener."

Four words. And the trap is that they sound finished — like the problem arrived fully specified and the only thing left is to draw it. Take a long link, hash it, store the mapping, hand back the short one. That's a hash map. You could write it on the flight over.

Now watch what happens when a candidate asks six questions first.

A hero figure showing that one system design prompt produces two completely different systems depending entirely on the requirements the candidate elicits. At the top sits a card holding the prompt every candidate is given: design a URL shortener. A vertical decision spine drops from the card and branches twice. The first branch is labelled ASKED NOTHING in red and leads to a single grey server box captioned one box, a hashmap; the verdict printed beside it reads: looks solved, but you cannot defend one line of it. The second branch is labelled ASKED SIX QUESTIONS in green and leads to a real left-to-right architecture built from four components: a CDN edge, then a Redis cache, then a redirect service running as N instances, then a primary store with two read replicas beside it. Beneath each component a dashed tie runs down to the specific quantified requirement that bought it. The CDN edge is tied to a p99 redirect target under 100 milliseconds. The Redis cache is tied to a measured hundred-to-one ratio of reads to writes. The redirect service fleet is tied to ten thousand peak redirects per second. The replicated store is tied to a 99.99 percent availability target. A note running under the four requirement chips states plainly that every box above was bought by an answer below it, making the causal direction unmistakable: the architecture did not come from the candidate's taste or from a memorized diagram, it came from facts that had to be asked for. The closing line delivers the lesson's thesis in two parts: a requirement you cannot point back to is a decision you cannot defend. The figure's argument is that non-functional requirements are not trivia to be recited at the start of an interview and then forgotten; they are the input that decides the shape of the system, and the entire distance between a toy and a real design is the set of questions the candidate thought to ask before drawing anything. Read the two branches side by side and the asymmetry is stark: the upper path is not wrong so much as unfounded, since nothing in it can be argued for or against, while every element of the lower path arrives already carrying its own justification.

Same four words. Same features — you still create links and you still redirect them. But the second system has a cache, an edge tier, a fleet, and replicas, and every one of those boxes traces back to a specific answer. The cache isn't there because caches are good; it's there because someone said a hundred reads for every write. The replicas aren't there for decoration; they're there because someone said four nines.

That's the whole lesson, and it's worth saying flatly before we go anywhere else:

The features tell you what to build. The requirements tell you what to build it out of.

Which means the requirements phase isn't the polite throat-clearing before the real design. It is the design — the part where you decide what the system has to survive. Do it well and everything downstream has a reason. Skip it and you spend forty minutes drawing boxes you cannot justify, and the interviewer will find that out with one question.

Why they left it vague

First, kill the suspicion that the vague prompt is laziness or a trick. It's neither. The interviewer is withholding information on purpose — information you can only get by asking. One senior-interviewer guide puts it exactly that way: the prompt is deliberately under-specified, and the missing pieces are the ones you can only get if you ask the right questions.

Why run it that way? Because it's the closest simulation of the actual job. Real work doesn't arrive as a spec. It arrives as "users should be able to share files" or "search feels slow." Somebody has to turn that into a system, and the turning-into is the skill being measured. The same guide is blunt about the proportions: good design is seventy percent or more requirements and planning. Not seventy percent drawing.

There's a corollary that's easy to miss and very useful. If the interviewer volunteers a specific detail, it is load-bearing. Nobody mentions "oh, and about ninety percent of reads hit the same five percent of links" as small talk. They said it because they expect it to show up in your design. Treat every unprompted number as a hint you've been handed for free.

You already met the vocabulary for this in Fundamentals of System Design — availability and the nines, latency versus throughput, the first taste of the consistency trade-off. This lesson isn't re-teaching what those words mean. It's about getting the right ones, with numbers attached, out of a person who is deliberately not volunteering them — and then actually holding yourself to them.

The questions that carry a decision

You have roughly five minutes. You cannot ask everything, and trying to is its own failure mode. So the skill isn't asking questions — any nervous candidate can do that. The skill is asking the few whose answers would change what you draw.

Here's the test, and you can apply it silently before every question: if the answer came back either way, would my design look different? If no, don't ask it. It costs clock and buys nothing.

Start with what it must do. Functional requirements are best phrased as plain capability statements — "users should be able to…" — and you're hunting for the top three, not an exhaustive catalogue:

  • "What are the core actions — just shorten and redirect, or also analytics, expiry, custom aliases?"
  • "Who's using this — the public internet, or one company's internal tools?"
  • "Is there anything you'd explicitly like me to leave out?" (That last one is a gift: it gets the interviewer to hand you your own scope reduction.)

Then chase the access pattern, because this is the highest-leverage question most candidates never ask. How the data is read determines how it must be stored — it is, as one guide puts it, probably the single most influential input to the design. Phrase it as "given this, get all of that":

  • "What's the read-to-write ratio?"
  • "Is traffic uniform, or is there a hot minority — a few links taking most of the redirects?"
  • "Do we ever need to go the other way — given a long URL, find its short codes?"

Then the qualities, with numbers. These are the non-functional requirements, and they're the ones the lesson title is pointing at:

  • "What latency should the redirect feel like?"
  • "How available does this need to be — what actually happens when a redirect fails?"
  • "When a link is created, must it resolve everywhere instantly, or is a short delay fine?"
  • "How big are we talking — links per month, redirects per second at peak?"

Four or five questions from these three groups and you will know more about the system than most candidates learn in the entire interview. Notice what's not on the list: what language to use, what cloud provider, what the UI looks like, how big the team is. Those answers change nothing on the board, which is exactly why they're the wrong questions.

Say it with a number

Here's the line that separates a real requirement from a decorative one.

"The system should be low latency." — worthless. Nobody was going to propose a slow one. It rules nothing out, so it decides nothing.

"Redirects should be under 100 milliseconds at p99" — the slowest one percent of requests, not the average — now you have something. That number eliminates a cross-region database round trip. It argues for an in-memory cache. It might buy an edge tier. One number, three design consequences.

A small phrasing habit makes this automatic. State functional requirements as "users should be able to…" and non-functional ones as "the system should…" — and then refuse to finish that second sentence without a number in it. "The system should be fast" doesn't survive the rule. "The system should serve redirects in under 100 milliseconds at p99" does.

So: an unquantified requirement is a wish. Highly available is a wish; 99.99%, which is about fifty-two minutes of downtime a year is a requirement. Scalable is a wish; ten thousand redirects a second at peak is a requirement. Secure is a wish until you can say what you're protecting and from whom.

If the interviewer won't give you a number — and sometimes they won't, deliberately — you propose one and get it confirmed: "I'll assume peak is around ten thousand redirects a second — reasonable?" That's not guessing. That's making your assumption visible so it can be corrected, which is precisely the behaviour the phase is scored on. A stated assumption is a design input. An unstated one is a landmine you'll step on in twenty minutes.

(You don't need to do the arithmetic yet. Turning these numbers into storage, bandwidth and server counts is its own craft — Back-of-the-Envelope: Estimate Like an Engineer covers it, and the timed method for when to do the math is the next lesson's job. Right now you only need the targets, on the board, agreed.)

Which requirements actually matter

There's a checklist floating around every interview prep site — availability, scalability, latency, durability, consistency, security, compliance, fault tolerance — and candidates recite it like an incantation. Reciting it is worth nothing. A requirement earns its place only if it changes the board.

That's the filter. For each candidate requirement, ask: what would I draw differently if this were true, and what would I draw differently if it weren't? If both answers are the same picture, it isn't a requirement for this system — it's noise you've imported from a checklist. Here's what surviving that filter looks like.

A reference figure mapping each quantified answer a candidate elicits to the concrete architectural move that answer earns, with the right-hand column drawn as real miniature diagrams instead of words, so the reader sees the structure a number buys rather than a label for it. The figure has two columns, headed THE ANSWER YOU GOT and WHAT IT BUYS YOU, and six rows. Row one: an answer of a hundred to one reads buys caching the hot path, drawn as a service box with an arrow into a cache chip. Row two: a p99 latency target under 200 milliseconds buys pushing work to the edge, drawn as a CDN globe node fanning out along three lines to three edge points of presence. Row three: a 99.99 percent uptime target buys replication and failover, drawn as a primary database cylinder with a replica cylinder beside it and a sync arrow between them. Row four: ten thousand writes per second buys sharding the write path, drawn as three database cylinders sitting on a common bar. Row five: a correctness requirement of no double-charge buys quorum writes and choosing consistency over availability, drawn as a database cylinder with a padlock beside it. Row six: an answer that stale reads are acceptable buys cheap asynchronous replication and, just as valuable, explicit permission not to over-engineer consistency, drawn as two database cylinders joined by a dashed asynchronous link. Each answer sits in a colour-matched chip and an arrow carries it into its move, so the direction of causation always runs from the elicited fact to the structure. The closing line states the test that decides whether a requirement was worth the airtime at all: no number and no consequence means it is a wish, not a requirement. Together the rows answer the question in the lesson's title — the non-functional requirements that matter are exactly the ones whose target forces a structural choice, and no others. Read left to right the map is a design aid, telling you which move an answer entitles you to make; read right to left it is a defence, letting you trace any component on your board back to the elicited fact that justifies its existence.

Read that map in both directions, because both directions are useful.

Left to right is how you design: the answer you got tells you the move you're entitled to make. Right to left is how you defend. When the interviewer asks "why is there a cache here?" — and they will — the strong answer isn't "caches make things faster." It's "because reads outnumber writes a hundred to one and we're targeting sub-100-millisecond redirects; without a cache we're going to the database on the hot path for every single redirect." Same cache. Completely different signal.

Which exposes the quiet cost of skipping the requirements phase: you don't just lose the requirements, you lose the justification for everything downstream. Every box becomes "because that's how these are usually built." That answer reads as recall, and recall is the cheap half of the scorecard.

One row on that map deserves special attention, because it's the one people misread as a non-answer. "Eventual consistency is fine here." That is not the interviewer declining to give you a requirement — that is them handing you permission not to over-engineer. It buys you cheap asynchronous replication and it takes quorum writes and distributed locks off the table. Knowing what you don't have to build is worth exactly as much as knowing what you do, and it costs a lot less time.

Cut it down to the few

Suppose the questions went well and you now have a dozen facts. This is the moment where candidates who did the hard part well still lose the phase — by writing all twelve on the board and treating them as equals.

A long list of requirements hurts you more than it helps. Every requirement you commit to is a promise you now owe a design for. Twelve promises in forty minutes means twelve shallow answers, and shallow reads as doesn't know what matters — which is the opposite of the signal you want. Aim for three core features and three to five load-bearing quality targets. That's it.

The sorting is easier than it sounds if you say it out loud in three buckets:

  • Must — the system is pointless without it. Creating and redirecting a link. The latency target. The availability target.
  • Should — genuinely valuable, genuinely not today. Custom aliases. Click analytics.
  • Won't — and say this part out loud. User accounts, link editing, an admin dashboard.

That third bucket is the one people skip, and it's the highest-value one in the room. Naming what you're not building does three things at once: it proves you saw the thing you're cutting (so it doesn't look like an oversight), it protects your clock from your own rabbit holes, and it gives the interviewer a clean moment to say "actually, I do want analytics" — which is far better to hear in minute four than minute thirty.

And if you genuinely can't tell whether something is a must or a should: ask. "Is analytics core here, or should I treat it as a bonus if there's time?" You are allowed to make the interviewer help you prioritize. Most of them are pleased to.

Commit — the move almost everyone skips

Two candidates ask identical questions and get identical answers. One goes on to a strong interview and the other doesn't. The difference is a single move that takes about fifteen seconds, and most people never make it.

Elicit and prioritize are the famous two. Commit is the third, and it's the one that turns a pile of facts into something you can be held to — and, more importantly, something you can hold the interviewer to.

A figure breaking the requirements phase of a system design interview into its three verbs, drawn as three numbered steps joined by a vertical spine so they read as one sequence. Step one, ELICIT, is subtitled ask only what changes the design, and is drawn as a real two-line dialogue rather than a checklist: a candidate speech bubble asking what the read-to-write ratio is here, answered by an interviewer speech bubble replying about a hundred reads for every write. Drawing it as speech makes the point that requirements are gathered in conversation, not recited. Step two, PRIORITIZE, is subtitled a few carry the design, the rest are noise, and is drawn as three labelled groups of bars holding real requirements. The MUST group holds three solid green bars reading create plus redirect, 100 to 1 reads, and p99 under 100 milliseconds. The SHOULD group holds two amber bars reading custom alias and click analytics. The WON'T group, labelled with the instruction to say so out loud, holds two dashed red bars struck through, reading user accounts and link editing — because naming what you are not building is part of prioritising, not an afterthought. Step three, COMMIT, is subtitled say it back, get the nod, design to it, and is given the most room because it is the move candidates skip. It is drawn as a scope card carrying the exact recap script to say aloud: so create and redirect are the core, a hundred to one reads, sub-100ms redirects, four nines, analytics is out of scope, I'll design to that, sound right? A green circled check mark beside the card stands for the interviewer's nod — the agreement that turns a list of facts into a contract. The closing line delivers the lesson: eliciting requirements without committing to them is just small talk, because only a scope you have committed to can be designed against, and only a scope you designed against can be defended when the interviewer pushes back. The vertical spine joining the three numbered steps carries the further point that these are not three separate activities but one continuous move, and that stopping after the first two — which is what most candidates do — leaves the work unfinished.

Committing is four small actions:

Write it down. On the canvas, in a corner you don't erase. Not in your head. A visible scope list is something you and the interviewer can both point at for the next forty minutes, and you will point at it.

Say it back. This is the actual move, and it's one sentence:

"So: create and redirect are the core. A hundred to one reads, sub-100-millisecond redirects, four nines. Analytics is out of scope. I'll design to that — sound right?"

Get the nod. Wait for it. If they correct you, you just saved yourself thirty minutes of designing the wrong system, in exchange for four seconds of silence. That is the best trade available anywhere in the interview.

Then design to it — and defend from it. This is where the commitment pays out. Every structural choice from here should be traceable to a line in that scope: choose the datastore from the requirements, not from habit; justify the queue from the requirements, not from the fact that queues are what one puts in diagrams. When you're challenged, the move is always the same — point back. "We said four nines, so a single primary is a single point of failure — that's why there's a replica and a failover path."

There's one more reason to commit out loud, and it's the least discussed. It transfers part of the risk. Once the interviewer has nodded at your scope, a design that satisfies that scope is a design that satisfies the agreement you both made. Without the nod, you're solving a problem you invented, and any gap between your imagined problem and theirs lands entirely on you.

Run the room yourself

Reading about eliciting requirements is a bit like reading about swimming. Below is the room: you get the same four-word prompt, a pool of clarifying questions, and an interviewer who answers whatever you actually ask.

Three things to feel, and you'll need more than one run to feel them all. One: some questions come back with a fact that changes the design and some come back with nothing — and the clock spends the same either way. Two: when you commit, everything you locked in lights up with the architecture it just bought you, and everything you committed out of habit shows up as dead weight you now owe an explanation for. Three — and this is the one worth running twice for — skip the questions entirely and go straight to committing. Watch the blind spots appear: not "you forgot a requirement," but you can no longer justify the cache, because you never established that this thing is read-heavy.

Ask the interviewer whatever you like, then commit a scope — and see which architecture each committed requirement earns you, and which choices you can no longer defend.

Where this goes wrong

Seven ways this phase fails. The first three are the famous ones; the last four are the ones that quietly sink people who thought they'd done it right.

1. Drawing before scoping. The most expensive five minutes in the interview. It reads as junior instantly, because the one thing seniority looks like from the outside is refusing to build before you know what you're building.

2. Asking everything. The overcorrection. Fifteen questions, the interviewer's patience thinning, and the clock gone. Ambiguity is part of the test: ask enough, state your assumptions for the rest, and move. Nobody is scoring completeness of interrogation.

3. Requirements with no numbers. "It should be fast and highly available" is a sentence that decides nothing and therefore justifies nothing.

4. Gathering, then ignoring. The subtle one. You ask good questions, get good answers, write them down — and then design from habit, never pointing back once. The requirements were theatre. An interviewer notices this immediately, because your justifications stop being about this system.

5. Listing everything, prioritizing nothing. Twelve equal-weight requirements is not thoroughness. It's an unwillingness to decide, performed as thoroughness.

6. Silent assumptions. You quietly decided single-region, or that eventual consistency is fine, and never said it. If it's load-bearing, say it: "I'm assuming eventual consistency is acceptable here — correct?" Cheap to say, expensive to skip.

7. Vanity requirements. Secure. Maintainable. Scalable. Cost-effective. Recited with no target and no consequence. They cost you the one thing the phase is short of — time — and they buy exactly nothing, because none of them rules anything out.

What a committed scope buys you

Five minutes, three questions groups, three buckets, one sentence of commitment. What you get back is out of all proportion to what it costs.

You get a design you can justify, because every component traces to a line you both agreed on. You get a defence against your own rabbit holes — when you feel yourself drifting into a lovingly-detailed analytics pipeline, the scope on the board says analytics is out. You get a shared definition of done, so you and the interviewer are grading the same system. And you get the thing that's hardest to fake: you sound like someone who has shipped systems, because this is precisely what shipping one starts with.

There's one honest limit worth naming. A committed scope is not a cage. If the interviewer pushes the problem sideways in minute twenty-five — "now suppose every link needs analytics" — the right response is never "we agreed that was out of scope." It's "we scoped that out, so let me re-open it: here's what changes." The commitment exists to keep you honest, not to keep you rigid. Being visibly willing to re-scope when the facts change is itself a strong signal.

You now know how to find out what you're building and how to hold yourself to it. What you don't have yet is the clock — how many minutes this phase actually gets, what comes after it, and how to run the whole forty-five without drifting. That's The Delivery Framework, next.