Functional vs Non-Functional Requirements Explained
- Shawn West
- Mar 30
- 9 min read
Updated: Aug 17
Teams can recite the difference between functional and non-functional requirements and still ship a system that fails on the non-functional half. The taxonomy was never the hard part. The hard part is that an NFR without a bound has no failing case — and a requirement with no failing case cannot be violated, which means it will never be a decision. Here's the mechanism, and the shape that fixes it.
The definitions are easy, and almost everyone already has them. Functional requirements describe what the system does. Non-functional requirements describe how well it does it. You can learn that in ninety seconds and repeat it in an interview.
So why do teams who can recite it perfectly still ship the failure it predicts?
Because knowing the category doesn't produce the requirement. The split is a filing system, and filing systems don't catch anything. What catches things is whether a given line in your requirements document can be wrong — whether there exists some observable state of the world that would let an engineer point at the running system and say "that violates this." Functional requirements get that property almost for free. Non-functional requirements almost never get it by accident, and most teams never give it to them on purpose.
The requirement that cannot be violated
Here's the test that separates a real requirement from a decoration, and you can run it on your own document in about twenty minutes.
Take each line. Ask: what would I have to observe to declare this violated? Write the answer next to it. Not "it would feel slow" — an actual measurement, taken somewhere specific, compared against something.
Do this for "the system shall allow users to reset their password via email" and the answer is immediate: a user requests a reset, no email arrives, violated. Anyone on the team can produce that state on demand, which is why it will get a test.
Now do it for "the system shall be performant." There is no answer. There is no measurement you could take that would settle the question, because no threshold was ever named. The line survives every review, satisfies every checklist, and constrains nothing.
Count the lines in your NFR section that failed this test. That number — not whether your team can define "non-functional" — is the honest measure of your requirements quality.
One fork, walked
The following is a composite drawn from patterns common in claims and policy-administration work; the figures are illustrative, not measured.
An insurance client — call the project Meridian — was replacing a claims-search portal used by adjusters. The functional requirements were genuinely good. Search by claimant name, policy number, date range, or adjuster. Results paginated at 25. Matching terms highlighted. Permission-filtered so an adjuster sees only their region's claims. Eleven functional requirements, each testable, each tested, all passing.
The non-functional section had four lines. Three were compliance restatements. The fourth read: "The system shall be performant and provide a responsive user experience."
UAT ran against a seeded environment of roughly 8,000 claims. Search returned in about 400 milliseconds. Everyone signed.
Production held 2.1 million claims across eleven years of history, because the legacy system had never archived anything. The first Monday of the month — the volume peak, when adjusters work the prior month's backlog — a name search took nine seconds. Adjusters started opening three browser tabs and firing the same search in each, hoping one would return first. That tripled the query load, which pushed the median past twelve seconds, which caused more tab-opening.
Notice what did not happen. No test failed. No requirement was violated, because none could be. The team had built precisely what was written, and what was written could not distinguish between the system they shipped and a system that worked.
The fix took nine weeks: a search index, an archive tier for claims older than seven years, and a rewritten permission filter that had been applying itself after the result set was assembled rather than inside the query. All three were architectural. All three would have been cheap to decide up front and expensive to retrofit — which is the entire reason NFRs have to arrive before the design, not after it.
The discovery move that would have caught it
The requirement wasn't missing because nobody cared about speed. Everybody cared about speed. It was missing because nobody asked the question that turns caring into a number.
That question is: "What is the largest real dataset this will run against in its first year, who owns that number, and where did they get it?"
Three parts, and all three matter. Largest real dataset forces someone to go look rather than estimate from the test fixture. Who owns that number attaches a name, so it can be wrong and someone can be accountable for it being wrong. Where did they get it separates a measured figure from a comfortable one.
On Meridian, that question had an available answer the whole time. A DBA could have run a row count in under a minute. The 8,000-claim UAT fixture wasn't a considered decision about representative scale — it was whatever the seed script happened to generate, and nobody ever compared it to production because nobody was asked to.
This is the discovery-first move in its plainest form: the failure was not a coding failure or a testing failure. It was a question nobody asked during elicitation, and it cost nine weeks. If you want the general form of this move, Requirements Elicitation Techniques That Work covers which instrument surfaces which kind of unstated constraint.
Run this on your current project: for the top three NFR categories in your domain, write down the scale figure you're designing against and the name of the person who owns it. Any blank is an unasked question.
Why the non-functional half goes missing
It's tempting to attribute this to carelessness. It isn't. There are structural reasons NFRs lose, and they're worth naming because each one has a different counter.
Why it goes missing | What's actually happening | The counter |
Nobody requested it | Functional requirements arrive from users; NFRs arrive from engineering judgment, which has no requester | Assign an owner per NFR category, not per feature |
It's hard to quantify | "Fast" is easy to say and hard to bound; naming a threshold means being wrong in public | Use a published reference point as the starting bound, then adjust |
It can't be demoed | A feature shows in a sprint review; a p95 that stayed flat shows nothing | Put the measurement on the same dashboard as delivery |
It has no failing case | With no bound, no observation can violate it, so it never becomes a decision | Require a bound + condition on every NFR line |
It's assumed baseline | "Obviously it should be secure" — assumed by everyone, specified by no one | Write the baseline down once as Definition of Done |
The fourth row is the load-bearing one. The others are aggravating factors; that one is the mechanism. An NFR with no bound isn't a weak requirement — it's not a requirement at all, in the same way that a test with no assertion isn't a test.
The four parts of an NFR that works
A usable non-functional requirement has four components. Drop any one and it degrades toward the Meridian line.
The quality attribute — what is being constrained. Response time, availability, recovery point, conformance level.
The bound — the number. 500ms. 99.9%. Fifteen minutes. WCAG 2.1 AA.
The condition — the circumstances under which the bound holds. This is the part Meridian was missing, and it is the part most often dropped. Under what load, against what data volume, over what measurement window.
The qualifier — how the measurement is interpreted. p95, not mean. Measured monthly, excluding scheduled maintenance.
Applied to Meridian, the line becomes:
The system shall return claims-search results within 1.5 seconds at p95, measured server-side, for queries against the full production corpus (currently 2.1M claims, owner: Data Platform lead), at the first-Monday concurrency peak of approximately 340 simultaneous adjusters.
That sentence is longer and uglier than "the system shall be performant." It is also worth roughly nine weeks, because an architect reading it before design starts will immediately conclude that a naive LIKE query against the claims table will not do — which is the whole point. The requirement did the work in review instead of in production.
For the bound itself, you often don't need to invent a number. Nielsen's long-standing response-time thresholds — roughly 0.1s for "instantaneous," 1s to preserve flow of thought, and 10s as the limit of attention — give you a defensible starting point for interactive latency (Nielsen Norman Group). ISO/IEC 25010 gives you the category list so you can check what you've forgotten. Accessibility has a conformance level rather than a number, which is why "WCAG 2.1 AA" is a complete bound on its own.
Run this on your current project: take your three most important NFRs and check them for all four parts. In our experience the condition is the one missing, and it's the one that made Meridian fail.
Where they live once they exist
Writing the NFR is half of it. A requirement that lives only in a document that nobody opens after kickoff will drift out of the team's daily work within a quarter. There are three homes, and they suit different NFRs.
Approach | Best for | Cost | Failure mode |
Acceptance criteria on the story | NFRs that vary per feature — one endpoint that must be faster than the rest | Low; rides existing process | Gets dropped when the story is split |
Definition of Done baseline | Universal NFRs — accessibility, auth, logging | Low ongoing, high to establish | Becomes ritual; nobody re-checks it |
Dedicated NFR backlog items | Improvements with real work behind them — cutting p95 from 3s to 1s | High; competes with features | Deprioritized indefinitely against feature work |
Most teams need all three, and the sorting rule is simple: if it varies by feature, it's acceptance criteria; if it's universal, it's Definition of Done; if closing the gap is a project, it's a backlog item. Getting this wrong is how a genuine architectural need ends up as a checkbox nobody reads. If your team's Definition of Done is doing more work than it can carry, Definition of Done vs Acceptance Criteria draws the line between the two.
The exception: when not to specify
This is not an argument for a large NFR set. An over-specified NFR document is its own failure mode — twelve pages of bounds nobody measures produce exactly as much value as no bounds at all, plus a maintenance burden and a false sense of rigor.
Skip the formal NFR when all three of these hold:
The blast radius is small. An internal tool with nine users and no external exposure does not need a documented availability target.
The cost of being wrong is a fix, not a rebuild. If discovering the constraint late means an afternoon of tuning rather than a re-architecture, you can afford to discover it late.
No external party will ask for evidence. Regulated, safety-critical, and contractual work removes this exception entirely — there, the documentation is the deliverable.
Meridian failed all three. Two million records, a nine-week architectural fix, and an insurance regulator in the background. That's the profile where the up-front bound pays for itself many times over.
The honest heuristic: specify the NFRs whose violation would change the architecture, and let the rest be discovered. Most products land somewhere between ten and twenty-five such lines. If you have eighty, you're documenting; if you have two, you're hoping.
The diagnostic
You don't need a project to start. Take the requirements document for whatever you're building now and do three things:
Mark every line that has no failing case. For each, either give it a bound and a condition, or delete it — a line that can't be violated is costing you review time and returning nothing.
For your top three NFRs, name the owner of the scale figure. Not the requirement's owner: the owner of the number. Blanks are unasked questions.
Check which of your NFRs would change the architecture if they doubled. Those are the ones that must be settled before design. The rest can wait.
The functional half of your requirements will get attention because users ask for it and demos reward it. The non-functional half only gets attention if somebody makes it capable of being wrong. That's the job, and it's mostly a writing job — four parts per line, one uncomfortable question per assumption.
The system that does everything it was asked to do, nine seconds at a time, passed every test it was given. It was given the wrong tests, because it was given the wrong requirements, because nobody asked how many rows were in the table.
Next: once your requirements are testable, the question becomes which ones to build first — see The MoSCoW Method for Prioritizing Requirements. If you're still upstream of that, Writing Good Requirements: A Step-by-Step Guide covers turning a vague ask into a testable line.
Sources
ISO/IEC 25010:2011 — Systems and software Quality Requirements and Evaluation (SQuaRE): System and software quality models — the standard characteristic list used to check NFR coverage.
ISO/IEC/IEEE 29148:2018 — Requirements engineering — defines the characteristics of a well-formed requirement, including verifiability.
Nielsen Norman Group, Response Times: The 3 Important Limits — the 0.1s / 1s / 10s thresholds, after Miller (1968).
W3C, Web Content Accessibility Guidelines (WCAG) 2.1 — conformance levels A, AA, AAA.


