Defining Requirements: What a System Must Do and How Well
In this lesson8 sections
"Design a chat app," the interviewer says, and slides a marker across the table. The candidate stands up and starts drawing: a box for the server, a box for the database, a line between them. Two minutes later the interviewer interrupts. "Chat for whom? Two friends, or a company with a hundred thousand employees? Do messages have to arrive in order? What happens if someone is offline for a week?" The candidate has no answers, because they never asked. The boxes on the board are a design for a product nobody has described.
This hypothetical exchange shows the cost of an unstated assumption. A design for one-to-one chat may not support a large company’s group, retention or access-control requirements. Confirm those needs early, then revise the design as the requirements become more precise.
Requirements are the fix. Before you draw a single box, you write down what the system must do and how well it must do it. That sentence contains the two kinds of requirements this lesson is about.
What you will learn
By the end of this lesson you will be able to:
Distinguish functional requirements from quality requirements and explain how both shape the architecture.
Turn a vague wish into a requirement that can be tested.
Gather requirements in an interview by asking the right questions in the right order.
Put numbers on the qualities a system promises: availability, latency, throughput, and the rest.
Recognize when two requirements conflict, and make the trade-off on purpose.
Two questions every design starts with
Every system, whether a chat app, a bank, or a smart thermostat, can be described by answering two questions.
What must it do? These are the functional requirements. They are the verbs: send a message, show the chat history, tell me who is online. If a feature is missing, a functional requirement was not met.
How well must it do it? These are the non-functional requirements. They describe qualities rather than actions: how fast, for how many users, with how much downtime, how safely. If the app works but takes ten seconds to open a chat, every functional requirement has been met and the product is still a failure. A non-functional requirement was not met.
The diagram below shows the split for an online store. On one side are the things it does: add to cart, process an order, show the catalog. On the other side are the qualities it must have while doing them: scale to the crowd, stay secure, respond quickly.
The names are a little unfortunate. "Non-functional" sounds like "does not work." A better way to hear it is "beyond the functions": everything the system must be, in addition to everything it must do.
Functional requirements: what the system does
A functional requirement describes one thing the system must be able to do, in language that someone could test. "A user can upload a photo" is a functional requirement. You can check it: try to upload a photo and see whether it works.
The enemy of a functional requirement is vagueness. "The app should be easy to use" is a wish, not a requirement, because two people would disagree about whether it has been met. Compare:
| Vague | Testable |
|---|---|
| The app should be easy to use. | A new user can sign up with one tap using their Google account. |
| Users should be able to fix mistakes. | A user can undo deleting a message for ten seconds after deleting it. |
| The system should handle groups. | A user can create a group of up to 500 members and send a message that every member receives. |
| Search should be good. | Searching for a word returns every message containing that word from the user's own chats. |
Each item on the right tells an engineer what to build and a tester what to check. That is the whole test of a functional requirement: could you write it on a card and hand it to someone?
Gathering them in an interview
In an interview, nobody hands you the requirements. The interviewer is playing the customer, and your first job is to interview them. This surprises candidates, who expect to be judged on the drawing. You are being judged on the questions first.
Here is how the opening of a chat app interview might go when the candidate does it well:
Candidate: Before I start, I want to pin down scope. Is this one-on-one chat, group chat, or both?
Interviewer: Both, with groups up to a few hundred people.
Candidate: Do messages need to arrive in order, and be stored so users can scroll back through history?
Interviewer: Yes to both.
Candidate: Should users see whether their contacts are online? And are we handling photos and video, or just text?
Interviewer: Online status, yes. Let's keep it to text for today.
Candidate: Got it. So in scope: one-on-one and group text messages, delivered in order, with history and online status. Out of scope: media. I'll write those down, then ask about how many users we expect.
Notice what happened. The candidate asked about features, drew a line between in scope and out of scope, said it out loud, and wrote it down. That last part matters. Requirements on the board keep both people honest for the rest of the hour.
Questions that almost always pay off:
What are the core actions a user takes? Which two or three matter most?
Which features are out of scope for today?
Who are the users? Consumers, employees, or other programs?
Is there anything the system must never do, such as show a message to the wrong person?
Every feature needs a home
Once the functional requirements are written down, each one has to land somewhere in the system. Take a plain messaging service. Its core functional requirements might be:
Users can sign up and log in.
Users can send a text message to another user or to a group.
Users can scroll back through their history with a person or a group.
Users can see whether a contact is online.
Users get a notification when a new message arrives.
The diagram below maps those features to the components that would own them. Sending a message and reading history belong to a messaging component backed by storage. Online status belongs to a presence component, a small service whose only job is to know who is connected right now. Signing in belongs to an authentication component. Profiles belong to a user component.
This mapping is more useful than it looks. It is the first moment a list of wishes turns into a list of parts, and it exposes gaps at once. If a feature has no box to live in, the design is not done. If a box has no feature pointing at it, ask why it exists.
Non-functional requirements: how well it does it
Quality requirements describe how the system must behave under specified conditions. Ask stakeholders what outcomes they need, and agree on how to measure them. For example, an availability target needs a defined operation, measurement window and rule for what counts as success.
Here are the qualities that come up in nearly every design, with the plain meaning of each and the kind of number you would attach to it.
| Quality | Plain meaning | A number you might attach |
|---|---|---|
| Scalability | It keeps working as users and data grow, by adding machines rather than rewriting. | Handle ten times today's users without a redesign. |
| Availability | It is up and usable, even when parts of it have failed. | Up 99.9 percent of the time. |
| Latency | It responds quickly. | A message appears on the other phone within 200 milliseconds. |
| Throughput | It handles a lot of work per second. | 10,000 messages per second at peak. |
| Durability | Accepted data remains recoverable under the stated failure model. | A sent message survives any single machine failing. |
| Consistency | All parts of the system agree on the data. | Two people can never both buy the last seat. |
| Security | Data and features are protected from people who should not have them. | Messages are encrypted in transit, and only members can read a group's messages. |
| Cost | It does all of the above within a budget. | Under an agreed amount per month at the target scale. |
The following table converts time-based annual availability targets into a downtime budget for a 365-day year. Each additional nine reduces that budget by a factor of ten. A request-based availability measure instead counts successful eligible requests, so it cannot always be translated directly into minutes of downtime.
| Availability | Allowed downtime per year | What it feels like |
|---|---|---|
| 99% (two nines) | About 3.7 days | Down for most of a long weekend |
| 99.9% (three nines) | About 8.8 hours | Down for one working day |
| 99.99% (four nines) | About 53 minutes | Down for one lunch break |
| 99.999% (five nines) | About 5 minutes | Barely noticed |
Higher targets can require more redundancy, faster recovery and stronger operational controls, but there is no universal architecture or cost multiplier for a given number of nines. Evaluate the failures the service must survive and test whether detection and recovery fit the budget. Five minutes during a critical sales event can still be highly visible to users.
Design example: A payment flow needs both functional behavior and quality guarantees: record a payment accurately, prevent duplicate effects when a request is retried, protect sensitive data and recover from dependency failures. Start by identifying the transaction boundary and retry behavior. Caches or extra data centers may help specific requirements, but neither is automatically required by the fact that the system handles payments.
How behavior and quality targets shape the architecture
Functional behavior and quality targets constrain the design together. Message ordering, access control and editing behavior affect the data model; traffic, latency and recovery targets affect how that model is deployed and operated.
A small messaging application might run on one server. A target of 10,000 messages per second, 99.99 percent availability and acceptable latency across three continents requires capacity estimates and a failure plan. It does not prescribe a cache or a specific number of regions by itself. Compare candidate designs against the workload and target before selecting components.
| Aspect | Functional requirements | Non-functional requirements |
|---|---|---|
| They describe | What the system does | How well it does it |
| Written as | Observable behavior and its conditions | Measurable targets, constraints or invariants |
| How to test | Define inputs, expected results and failure cases | Define the measurement, workload and acceptance rule |
| Who supplies them | Stakeholders and engineers, through clarification | Stakeholders and engineers, through agreed targets and constraints |
| Effect on the design | Decide which components exist | Decide how many, where they run, and how they connect |
Interview tip: After the feature questions, ask the scale questions and propose numbers yourself: "How many users? Let's say ten million, with a million active at once. Should we aim for 99.9 percent uptime?" Interviewers rarely have exact figures. They want to see you ask, pick something reasonable, and design to it.
When requirements fight each other
In a perfect world you would build a system that is infinitely fast, never down, perfectly consistent, completely secure, and cheap. In the real world those goals pull against each other, and a large part of system design is deciding which one wins when they collide.
Cross-node coordination can add latency. For example, a write that waits for a replica quorum depends on communication and processing at those replicas. The consistency model determines what readers may observe; strong consistency does not require every replica to acknowledge every operation. The Time, Ordering, Coordination, and Consistency section distinguishes these models and explains CAP’s specific tradeoff during a network partition.
A smaller collision, and a very common one: a social app wants to stop spam, so it adds a rule that a user may post at most ten comments a minute. That is a security-flavored requirement. Enforcing it means checking the user's recent history before every comment, which adds a little time to every request. Security has cost latency. The usual answer is to keep those counts in a very fast in-memory store so the check costs almost nothing. The two requirements are reconciled rather than one of them abandoned.
Real-world example: Over-promising on a quality costs as much as under-delivering. A team that commits to five nines when the business would be fine with three nines has signed up for roughly a hundred times less allowed downtime, and the engineering to match, for a benefit nobody asked for. Push back on a number before you design to it.
When there are more requirements than time or money, teams need a way to rank them. One simple method sorts every requirement into four buckets: must have, should have, could have, and will not have this time. For the chat app, sending messages is a must. Online status is a should. Stickers are a could. Video calls are a will-not, at least for this version. Writing the buckets down turns trade-offs from accidents into decisions.
Common traps
Drawing before clarifying scope. A brief requirements discussion helps prevent spending the session on a feature or workload the prompt did not ask for.
Unclear acceptance criteria. Define how to measure availability and latency, and express other constraints, such as access rules, as testable conditions.
Designing for a scale you do not have. Building for a hundred million users when you have ten thousand costs money and time, and usually gets the design wrong anyway, because you guessed.
Treating every quality as a must. If everything is top priority, nothing is. Rank them.
Forgetting the negative requirements. "Never show a message to the wrong person" is a requirement too, and often the most important one.
Knowledge check
Four questions. The first one has more than one correct answer.
Knowledge check
Check your understanding
4 questions · source answers hidden
Key takeaways
Functional requirements specify behavior; quality requirements and constraints specify the conditions under which that behavior is acceptable. Both influence the design.
Make requirements reviewable with expected outcomes, measurable targets or explicit invariants.
In an interview, gather features first, then propose numbers for scale, uptime, and speed, and write everything down where both of you can see it.
Define availability’s measurement window and denominator. Each extra nine reduces the allowed failure fraction tenfold, while implementation cost depends on the system.
Requirements collide. Decide which wins per feature, and rank the rest so that the trade-offs are deliberate.
The next lesson, Monoliths and Microservices: Choosing the Shape of a System, is the first big decision the requirements feed into. Should the product be one application or many? The answer depends on the team, the stage of the business, and the scale you just wrote down, and there is a sensible default most teams should start from.