What Is System Design?
System design is deciding how the parts of a software system fit together so it stays fast, reliable and affordable as it grows. Here is what that means and a step-by-step way to approach any design question.
In a nutshell
- System design is about trade-offs: every choice makes something better and something else worse.
- Start every design from requirements: what the system must do, and how well (speed, availability, scale).
- Use a repeatable approach: requirements, estimates, API and data, high-level design, deep dives, wrap-up.
- Interviewers look for clear thinking and justified decisions, not one "correct" architecture.
What system design actually is
When you write a program, you think about functions and classes. When you design a system, you zoom out: which servers run the code, where the data lives, how requests reach the right place, and what happens when something breaks or ten times more people show up.
Almost every app you use is built from the same small set of parts: clients (browsers and phones), servers that run the code, databases that keep data, caches that keep hot data close, queues that let work happen later, and load balancers that spread traffic. System design is choosing which of these parts you need and how to connect them.
The usual building blocks
Diagram as text
- Users → Load balancer: request
- Load balancer → App servers
- App servers → Cache: hot data
- App servers → Database: source of truth
- App servers → Queue: later
There is no single right answer. A design that is perfect for a startup with a thousand users would be wasteful at that size, and a design that is fine for a thousand users can fall over at ten million. Good system design means picking the simplest design that meets the requirements, and knowing what you would change as they grow.
Start from requirements
Before drawing a single box, find out what the system must do and how well. Requirements come in two kinds.
| Kind | Question it answers | Examples for a photo-sharing app |
|---|---|---|
| Functional | What does the system do? | Upload a photo, follow people, see a feed of photos from people you follow, like and comment. |
| Non-functional | How well must it do it? | Feed loads in under 200 ms, the app is available 99.9% of the time, uploads are never lost, it supports 10 million daily users. |
Non-functional requirements drive most design decisions. "Users can see a feed" is easy for a hundred users and a serious engineering problem for a hundred million. The usual non-functional requirements are:
- Scale: how many users, requests per second and how much data.
- Performance: how fast responses must be (latency) and how much work per second (throughput).
- Availability: how much downtime is acceptable.
- Consistency: whether every user must see the latest data immediately, or whether a few seconds of delay is fine.
- Durability: whether data may ever be lost.
- Cost, security and compliance, which often rule options out early.
A step-by-step approach
Whether you are in an interview or at work, the same six steps keep a design on track. Press Play to walk through them.
Six steps for any design
All steps Move from what is needed, to a rough shape, to the details that matter most.
- Requirements: agree on the features and on the non-functional goals such as scale, latency and availability.
- Estimates: work out rough numbers for requests per second, storage and bandwidth, so you know which parts will be under pressure.
- API and data: define the main API calls and the data you store. This makes the design concrete.
- High-level design: draw the main components and how a request flows through them.
- Deep dives: pick the hardest parts (the busiest path, the biggest table, a failure case) and design them properly.
Diagram as text
- Requirements: agree on the features and on the non-functional goals such as scale, latency and availability.
- Estimates: work out rough numbers for requests per second, storage and bandwidth, so you know which parts will be under pressure.
- API and data: define the main API calls and the data you store. This makes the design concrete.
- High-level design: draw the main components and how a request flows through them.
- Deep dives: pick the hardest parts (the busiest path, the biggest table, a failure case) and design them properly.
- Requirements. Ask questions until you can state the features and the goals in a few lines. Write them down.
- Estimates. Rough numbers: daily users, requests per second at peak, data stored per year. They tell you whether one database is enough or you need many.
- API and data model. List the main calls, such as
POST /photosandGET /feed?cursor=…, and the main tables or collections. - High-level design. Draw clients, load balancer, services, databases, caches and queues, and trace one request end to end.
- Deep dives. Go deeper on the parts that carry the most risk: the hot path, how data is split across machines, what happens when a server dies.
- Wrap-up. Name the bottlenecks, the trade-offs you made, and what you would change at ten times the scale.
Time plan for a 45-minute interview
- ~5 minRequirements and scope
- ~5 minEstimates
- ~10 minAPI, data model and high-level design
- ~20 minDeep dives on two or three areas
- ~5 minBottlenecks, trade-offs and wrap-up
What a good design shows
| Signal | What it looks like |
|---|---|
| Clarity | You state requirements and assumptions before designing, and your diagram matches what you say. |
| Trade-offs | For each big choice you name an alternative and why you did not pick it. |
| Numbers | Decisions are backed by rough estimates ("about 5,000 writes per second, so one database will struggle"). |
| Depth | You can go deep on at least one part: data partitioning, caching, consistency or failure handling. |
| Pragmatism | You start simple and add complexity only when a requirement needs it. |
Common mistakes
- Jumping straight to drawing boxes before agreeing on requirements and scale.
- Adding every buzzword (microservices, Kafka, sharding) to a system that does not need them yet.
- Giving one design without explaining what you traded away to get it.
- Spending the whole time on the high-level diagram and never going deep on anything.
- Ignoring failure: what happens when a server, a database or a whole data centre goes down.
Interview questions
Try answering out loud before you open each one.
How would you start if you were asked to design a news feed?
Do not start with the architecture. Ask about the features (posts with text and images? likes? ranking or newest first?), the scale (daily users, posts per day, how many people a user follows), and the goals (how fresh the feed must be, acceptable latency). Then state the numbers you will design for and confirm them with the interviewer.
What is the difference between functional and non-functional requirements?
Functional requirements say what the system does, such as "users can post a photo". Non-functional requirements say how well it must do it: latency, availability, scale, durability, consistency and cost. The non-functional ones usually decide the architecture.
Why do interviewers ask for estimates?
Numbers decide whether a simple design is enough. Ten writes per second fit on one database; fifty thousand do not. Estimates also show you can reason about capacity instead of guessing.
Check yourself
Related topics
Further reading
- The System Design Primer Donne Martin, open source on GitHub
- Designing Data-Intensive Applications Martin Kleppmann, O'Reilly
Your notes
Saved in this browser as you type.
Finished this topic?
Mark it read to track your progress, then carry on with the next one.