Intuition The 80/20 of this note
Before writing any code, you must answer two questions: WHAT must the system do? (functional) and HOW WELL must it do it? (non-functional). Everything else — user stories, acceptance criteria — is just a disciplined way of recording, slicing, and testing those two answers so nobody builds the wrong thing.
Imagine a builder who starts laying bricks before asking what kind of building or for whom . Code is the same: the most expensive bug is building the wrong thing perfectly . A requirement is a written agreement about what "done" means so the customer's mental picture and the developer's mental picture overlap.
The cost of fixing a misunderstanding grows roughly exponentially with how late it's caught:
Cost ( t ) ≈ C 0 ⋅ k t , k > 1 \text{Cost}(t) \approx C_0 \cdot k^{\,t}, \quad k > 1 Cost ( t ) ≈ C 0 ⋅ k t , k > 1
where t t t = stage (requirements → design → code → test → production). A requirements-stage fix costing C 0 C_0 C 0 becomes C 0 k 4 C_0 k^4 C 0 k 4 in production. WHY this matters: writing requirements is cheap leverage against the steepest part of this curve.
Definition Functional requirement (FR)
A statement of ==what the system must do == — a specific behaviour, input→output, or feature.
Test: "Can I phrase it as 'The system shall ...'?"
Definition Non-functional requirement (NFR)
A statement of how well the system must perform a quality — a constraint on speed, security, availability, usability, etc. Often called quality attributes or the "-ilities" .
Test: "Is it measurable with a number/unit, not a feature?"
Intuition The verb-vs-adverb test
Functional = the verb ("the system uploads a file").
Non-functional = the adverb ("...quickly , securely , reliably "). The same verb can carry many adverbs.
Aspect
Functional
Non-functional
Answers
WHAT it does
HOW WELL
Example
"User can reset password"
"Reset email arrives in < 5 s, 99% of time"
Failure looks like
Feature missing
Feature present but too slow/insecure
Verified by
feature test
benchmark / load / pen-test
Worked example Sorting one requirement into FR vs NFR
Requirement: "Customers can search products, and results return within 2 seconds even with 10,000 concurrent users."
FR: "Customer can search products." → Why? It's a behaviour (a verb).
NFR: "results within 2 s under 10,000 concurrent users." → Why? It's a measurable quality constraint (performance + scalability) on that behaviour.
"FURPS+" menu of NFRs
F unctionality, U sability, R eliability, P erformance, S upportability + (security, scalability, legal). When you've written the F , ask: "what about the URPS+ ?"
A small, user-centred description of a feature in the form:
As a ⟨ r o l e ⟩ , I want ⟨ g o a l ⟩ , so that ⟨ b e n e f i t ⟩ . \text{As a } \langle role\rangle,\ \text{I want } \langle goal\rangle,\ \text{so that } \langle benefit\rangle. As a ⟨ r o l e ⟩ , I want ⟨ g o a l ⟩ , so that ⟨ b e n e f i t ⟩ .
It captures who wants it, what they want, and why (the benefit justifies the cost).
Intuition WHY this exact template
As a <role> forces you to name a real user , not "the system" — prevents building features nobody uses.
I want <goal> keeps it a capability , not an implementation. (Goal: "find a cheap flight", not "add a SQL index".)
so that <benefit> is the value test : if you can't fill the benefit, the story may be worthless. It's your 80/20 filter for prioritisation.
INVEST
I ndependent, N egotiable, V aluable, E stimable, S mall, T estable.
Worked example Turning a vague request into a story
Stakeholder: "We need shopping cart stuff."
Story: As a shopper, I want to remove an item from my cart, so that I don't accidentally buy things I changed my mind about.
Why this step? The benefit ("don't accidentally buy") tells us removal must be easy and visible , which later shapes the UI and acceptance criteria.
Definition Acceptance criteria (AC)
The specific, pass/fail conditions a story must satisfy to be accepted. They turn a fuzzy story into something a tester (or automated test) can definitively check.
Intuition WHY stories need AC
A story says what & why ; it is deliberately negotiable and not precise enough to test. AC is the contract's fine print — it removes ambiguity ("works" → "given an empty cart, removing... shows the cart total = £0").
A popular HOW-format is Given-When-Then (Gherkin) :
Given ⏟ context/state When ⏟ action Then ⏟ expected outcome \underbrace{\textbf{Given}}_{\text{context/state}}\ \ \underbrace{\textbf{When}}_{\text{action}}\ \ \underbrace{\textbf{Then}}_{\text{expected outcome}} context/state Given action When expected outcome Then
Worked example Writing AC for the "remove item" story
Given a cart with 2 items, When I remove one, Then the cart shows 1 item and the total updates.
Why? Tests the happy path and that the total recomputes (a hidden requirement!).
Given a cart with 1 item, When I remove it, Then the cart shows an "empty cart" message.
Why? Tests the edge case — boundary conditions are where bugs hide.
Given a removed item, When I view the cart, Then it is not present after refresh.
Why? Forecasts a possible bug: removal only in UI but not persisted.
Worked example AC that also encodes an NFR
Story: As a user I want search results.
AC: Given 10,000 products, When I search "shoe", Then results appear in ≤ 2 seconds for the 95th-percentile request.
Why? Notice the number — AC is where non-functional requirements get a measurable threshold .
Common mistake "Performance is just part of the feature, no need to call it non-functional."
Why it feels right: users do experience slowness as the feature being broken, so it seems functional.
The fix: the feature can be 100% present and still fail. Splitting out the NFR forces an explicit, measurable target and a different kind of test (load test, not feature test). Without that split, "fast enough" stays an opinion.
Common mistake Writing the
how (solution) inside a user story.
e.g. "As a user I want a Redis cache so pages load fast."
Why it feels right: the dev already imagines the solution.
The fix: stories own the problem space (goal + benefit); the how is a design decision made later. Rewrite: "...I want pages to load quickly, so that I don't abandon the site." Now the team is free to choose Redis, a CDN, or nothing.
Common mistake Acceptance criteria with no edge/negative cases.
Why it feels right: the happy path is what we picture first.
The fix: for every "Then it works", add a Given an invalid/empty/boundary input case. Most production bugs live at boundaries (0 items, max length, no network).
Common mistake "Testable" only means a human clicks around.
Why it feels right: manual checking confirms the demo works.
The fix: an AC should be phrased so it could be automated and re-run forever (objective pass/fail, fixed inputs/outputs). "Looks nice" is not testable; "shows total = £0" is.
Talk to stakeholders → collect raw needs.
Split each need into FR (verbs) and NFR (measurable qualities).
Package user-facing FRs as user stories (role/goal/benefit), keep them INVEST .
For each story, write acceptance criteria (Given-When-Then) — including edge cases and any NFR thresholds.
Estimate, prioritise by benefit (80/20), build, then verify story is "done" only when all AC pass .
What single question does a functional requirement answer? WHAT the system must do (a behaviour/feature, a "verb").
What single question does a non-functional requirement answer? HOW WELL — a measurable quality/constraint (speed, security, availability...).
Give the 3-part user story template. As a , I want , so that .
Why does a user story include "so that "? It states the value, acting as the prioritisation/80-20 filter and justifying the cost.
What does the INVEST acronym stand for? Independent, Negotiable, Valuable, Estimable, Small, Testable.
What is an acceptance criterion? A specific pass/fail condition a story must meet to be accepted ("definition of done").
Name the three keywords of the Gherkin AC format. Given (context), When (action), Then (expected outcome).
Where do non-functional thresholds usually become concrete? In acceptance criteria, as measurable numbers (e.g. "≤ 2 s for 95th percentile").
Why split performance out as non-functional instead of part of the feature? A feature can be fully present yet too slow; the split forces a measurable target and a different test (load test).
What's wrong with "As a user I want a Redis cache so pages load fast"? It states a solution (how), not a goal; stories should stay in the problem space and leave design open.
What does FURPS+ remind you to check? Functionality, Usability, Reliability, Performance, Supportability + security/scalability/legal NFRs.
Why does fixing a requirements error cost so much more in production? Cost grows roughly exponentially per stage; a wrong assumption propagates into design, code, and tests.
Recall Feynman: explain it to a 12-year-old
Imagine you ask a friend to build you a sandwich. Functional = what goes in it: "bread, cheese, ham." Non-functional = how you want it: "ready in 1 minute, not too salty, cut into triangles." A user story is you saying why : "I'm a hungry kid who wants cheese & ham so I'm not hungry in class." Acceptance criteria are how your friend proves it's right: "Given I gave you bread, when you finish, then there's cheese AND ham, the bread isn't burnt, and it took under a minute." If any of those fails, the sandwich isn't "done" — even if it looks fine!
Mnemonic Whole-chapter hook
"What, How-well, Who-Why, Prove-it."
What = functional · How-well = non-functional · Who-Why = user story · Prove-it = acceptance criteria.
Software Development Life Cycle — requirements are the first SDLC phase.
Agile and Scrum — user stories live in the product backlog.
Test-Driven Development — acceptance criteria become automated tests.
Software Design — design answers the how that stories deliberately omit.
Stakeholder Analysis — the <role> in each story comes from here.
Estimation and Story Points — the "Estimable/Small" of INVEST.
Requirements = written agreement on done
Cost grows exponentially if caught late
Functional = WHAT it does
Non-functional = HOW WELL
Feature and benchmark tests
Intuition Hinglish mein samjho
Dekho, coding shuru karne se pehle do cheezein clear honi chahiye: WHAT system karega aur HOW WELL karega. "What" matlab functional requirement — koi behaviour ya feature, jaise "user password reset kar sakta hai". Ye hamesha ek verb (kaam) hota hai. "How well" matlab non-functional requirement — quality jaise speed, security, reliability. Jaise "reset email 5 second ke andar aaye, 99% baar". Yaad rakho: functional = verb, non-functional = adverb. Same feature ke saath bahut saare NFR chipak sakte hain.
User story ek chhota tarika hai requirement likhne ka jo user-centric ho: "As a , I want , so that ." Isme role real user ko force karta hai, goal capability batata hai (solution nahi!), aur so that value batata hai — yahi 80/20 filter hai, agar benefit nahi likh paa rahe to feature shayad bekaar hai. Ek galti jo sab karte hain: story me solution daal dena ("I want a Redis cache"). Galat! Story sirf problem batati hai, how baad me design wale decide karenge.
Acceptance criteria wo precise pass/fail conditions hain jo batati hain ki story "done" kab hui. Iska famous format hai Given-When-Then : Given = context/state, When = action, Then = expected result. Aur yahin par non-functional ke numbers concrete hote hain (jaise "≤ 2 seconds"). Sabse important tip: sirf happy-path mat likho — empty cart, invalid input, boundary cases zaroor add karo, kyunki asli bugs wahin chhupte hain.
Ye sab matter kyun karta hai? Kyunki galti requirements stage me 1 rupaye ki hai, lekin production me wahi galti hazaar rupaye ki ho jaati hai — cost har stage pe roughly exponentially badhti hai. To thoda time requirements likhne me lagao, baad me bahut paisa aur dimaag bachega.