Why this matters
A design must address its requirements. Otherwise, there is no reliable way to decide whether an architecture is suitable or to compare two valid alternatives.
Requirements fall into two groups:
- Functional requirements define what the system is supposed to do.
- Non-functional requirements define how the system is supposed to be.
For a messaging system, a functional requirement might be: “The system must allow applications to exchange messages.”
Its non-functional requirements might be: “The system should be scalable, highly available, and fast.”
Why interview prompts are ambiguous
During an interview, functional requirements are often stated ambiguously. Non-functional requirements may not be mentioned at all.
This is intentional. A generic prompt lets the interviewer observe how you:
- deal with ambiguity;
- identify the key parts of the system;
- clarify functional and non-functional requirements;
- define the scope of the problem.
These are useful signals because real engineering problems also arrive incomplete. The interviewer wants to understand how you would approach such a problem after joining the team.
Requirements guide trade-offs
System design problems are open-ended. Several concepts, patterns, and technologies may fit the same problem, and every option has trade-offs.
Non-functional requirements help navigate those choices. Even three qualities—scalable, highly available, and fast—already reveal a chain of design questions.
The following walkthrough is not a finished architecture. It shows how requirements activate relevant system-design knowledge.
Scalability: writes and storage
First ask what must scale: writes, reads, or both?
For a messaging system, the answer is probably both. Each message is written first and consumed later.
Scaling writes leads to partitioning. Instead of storing every message in one queue, distribute messages across multiple queues. A hash-based partitioning strategy may be a reasonable starting point.
The next question is where to store the messages:
- in memory, using a bounded queue;
- on disk, using an append-only log;
- on disk, using an embedded database.
If an embedded database is used, compare a B-tree with an LSM-tree. An LSM-tree may be preferable here because the workload emphasizes writes.
Scalability: reading messages
Partitioning also helps scale reads because each partition can have its own consumer.
Then choose how consumers receive messages:
- Push: the messaging system sends messages to consumers.
- Pull: consumers ask the messaging system for messages.
If the design uses pull, consider long polling. It can reduce the number of empty read requests while consumers wait for new messages.
High availability and replication
High availability leads to message replication. The next choice is between leader-based and leaderless replication.
Suppose leader-based replication is selected. The design must then handle leader election when the current leader is unavailable.
A coordination service or a database with strong consistency may be used to coordinate that election.
Notice the reasoning pattern: a requirement suggests a mechanism, and that mechanism introduces another design problem that must be solved.
Reliability and routing
The system may also need protection mechanisms such as:
- load shedding;
- rate limiting;
- shuffle sharding.
At this point, ask whether a reverse proxy should provide these mechanisms.
A reverse proxy may also simplify producer and consumer clients. It can take responsibility for partition discovery and message routing instead of duplicating that logic in every client.
Making the system fast
Speed leads to another set of decisions. Batching several messages can reduce per-request overhead, while compression can reduce the number of bytes transferred.
The client-server protocol also matters. If trusted clients access the system inside a trusted environment, TCP may be considered instead of HTTP.
This assumption must be clarified with the interviewer. The environment and client trust model determine whether that option is appropriate.
Work with the interviewer
The interviewer is a collaborator and a potential future teammate. They need enough evidence to understand your reasoning, not to watch you remain blocked.
Ask questions, state assumptions, and explain why a requirement leads to a particular design choice. If you become stuck, use the interviewer to restore shared context and continue the discussion.
You do not need to recognize every technical term immediately. What matters is learning which concepts address which requirements and building a connected mental model over time.
Requirements beyond interviews
The same skill applies to daily engineering work. A system design document should define:
- the scope of the problem;
- functional requirements;
- non-functional requirements;
- the relative priority of those requirements.
Design tenets are often expressed as intended system qualities, such as security, availability, and performance.
Order matters. A requirement placed higher on the list has greater priority. When several designs are viable, this ordered list acts as a tiebreaker.
Questions
- What is the difference between a functional and a non-functional requirement?
- Why might an interviewer intentionally leave requirements ambiguous?
- How does a scalability requirement lead from partitioning to storage-engine choices?
- Why does partitioning help both message writes and reads?
- What additional problem appears after choosing leader-based replication?
- How can a reverse proxy simplify messaging clients?
- When might TCP be considered instead of HTTP, and what must be clarified first?
- How can an ordered list of requirements resolve a design trade-off?
Key takeaways
- Functional requirements describe system behavior; non-functional requirements describe system qualities.
- Clarifying ambiguity and defining scope are part of system design, not preliminary paperwork.
- Requirements guide a chain of architectural questions rather than pointing to one automatic solution.
- Scalability can lead to partitioning, storage-engine choices, consumer topology, and long polling.
- High availability can lead to replication, leader election, and coordination mechanisms.
- Reliability and speed introduce load shedding, rate limiting, routing, batching, compression, and protocol choices.
- In design documents, prioritized requirements become tiebreakers between otherwise viable options.