What is system design?
SystemsMid priority~15 minChoosing which qualities a system buys for one set of requirements — and being able to name what you paid for them with.
Definition
System design turns a one-line ask — build a link shortener, build a group chat — into a concrete arrangement of components, data stores and protocols, plus the reasons that arrangement beats the ones you rejected. The artifact is not the drawing. The artifact is a set of choices, each attached to a requirement it serves.
The cost model is the thesis of this whole track: every quality is bought with another one. Low latency is bought with duplicated data you then have to keep fresh (caching); high availability is bought with redundancy, and redundancy is bought with hardware, coordination and weaker consistency (the CAP theorem).
In practice no design holds low latency, strong consistency, low cost and high availability at once. So a design is judged less by what it achieves than by whether you can say what you gave up first, and why that was the cheapest thing to lose.
Techniques
The two requirement classes
Every prompt splits into two kinds of requirement, and the axis that separates them is how you falsify one: a single request settles a functional requirement, while a non-functional requirement can only be judged over a population of them.
Miss a functional requirement and you build the wrong feature. Miss a non-functional one and you design the wrong system — and since the prompt almost never states them, missing them is what happens by default unless you go and ask.
| Functional requirement | Non-functional requirement | |
|---|---|---|
| What it states | What the system does | How well it does it, and under what load |
| The form it takes | A verb and an object — a user can shorten a URL | A number, a percentile and a window — 99% of redirects under 100 ms |
| Where it comes from | The prompt, plus clarifying questions | Almost never the prompt — you propose targets and get them confirmed |
| What it constrains | The API surface and the data model | The topology — replication, caching, sharding, how many regions |
| Chat-app example | Send a message; show delivery receipts | p99 delivery under 500 ms; 99.9% availability; ordered per conversation |
The qualities you trade
The non-functional half is drawn from a small reusable list — named here, taught one lesson at a time later.
- Availability — the fraction of time, or of requests, the system serves successfully.
- Latency and throughput — how long one request takes, quoted at a percentile, against how many requests per second the system absorbs. Two different problems.
- Reliability — whether it keeps producing the right answer, which is a different question from whether it answers at all.
- Durability — the probability that data, once acknowledged, survives.
- Consistency — whether a read is guaranteed to see the most recent write.
- Scalability — whether adding capacity keeps up with load.
- Cost and maintainability — the two candidates forget. AWS's Well-Architected framework makes them two of its six pillars.
Each of these gets a measurement (an SLI), a target for that measurement (an SLO), and sometimes a customer contract with penalties attached (an SLA). The Availability lesson owns those three and the arithmetic that turns a target into minutes of downtime.
The boxes you choose between
The other vocabulary is the components, and it is shorter than it looks: almost every design in this track is assembled from the same handful. A client issues requests. A load balancer spreads them across interchangeable, stateless application servers, which is what lets you add capacity by adding machines. A cache holds what is expensive to recompute; a database holds what has to survive a restart. A message queue takes work the caller shouldn't wait for. Observability watches all of it.
Design is deciding which of these you actually need and how many. Start from the smallest thing that could work — client, load balancer, application servers, database — and add a box only when a requirement demands it. The diagram below shows where each one sits when it is present, not a starting point to trim down.
Worked examples
Two verbs, two very different systems
Google's SRE Workbook walks one service end to end — the API behind a mobile game. Its functional half is the part you could have guessed from the name: a player submits a score, a player reads the leaderboard. Its non-functional half was measured, not guessed: four weeks of traffic gave starter objectives of 97% availability, 90% of requests under 450 ms, and 99% under 900 ms.
Look at what the numbers do that the verbs cannot. The 97% is not picked off a table of nines — it is the service's own observed success rate, rounded down, which is why it is 97% and not 99.9%. Two latency targets rather than one say the tail matters, not just the typical request. Keep the same two verbs and move those numbers to 99.99% and 50 ms and you have a different system: replicated, cached, multi-region, and an order of magnitude more expensive to run. The verbs never changed.
The Workbook also picks its indicators by service shape — request-driven services get availability, latency and quality; data pipelines get freshness, correctness and coverage; storage systems get durability. Choose the wrong menu and your targets measure nothing anyone cares about.
In the interview
The question arrives in nearly every design round, usually in the first five minutes: what are the non-functional requirements here? The answer that signals depth proposes numbers with a percentile and a window, attaches each to a design consequence, and volunteers which one you would give up first. For a link shortener: "99.9% availability on the redirect path, p99 redirect latency under 100 ms, and I'll take eventual consistency on click analytics — I'd rather lose a click count than a redirect." That last clause is the one that separates candidates: it names the sacrifice before anyone asks for it.
- Give every non-functional number a unit and a window. "p99 under 200 ms over a rolling 28 days" invites a design discussion; "fast" invites nothing.
- Don't reach for a big-company architecture before a requirement demands it — microservices, a message bus and a cache tier proposed at minute two are a signal against you (microservices).
- When two requirements fight, say so out loud and pick. Naming the conflict is worth more than resolving it quietly — and some sets are jointly unsatisfiable, which is a real answer (the CAP theorem).
- Two candidate designs can both be right — the track takes that as its own position, and Meta describes its 45-minute design round as almost never involving code. If you catch yourself hunting for the one intended solution, you are still in coding-interview mode.