Introduction to System Design
In this lesson8 sections
During the November 15, 2022 Eras Tour presale, Ticketmaster struggled with unusually heavy traffic. The company reported sending invitation codes to about 1.5 million fans and receiving 3.5 billion system requests, four times its previous peak. Its explanation attributed the traffic to both fans and bots. Ticketmaster’s account of the presale provides a concrete starting point for studying overload.
That account does not establish that every checkout component was correct. It does show why the behavior of the whole service matters: admission control, seat inventory, queues and payment processing must work together when demand exceeds normal levels. In a ticketing design, identify which requests can wait, how much work each component can accept, and how to prevent two successful purchases of the same seat.
Preventing that kind of day is what system design is about.
What you will learn
By the end of this lesson you will be able to:
Explain what system design is in one or two plain sentences.
Name the building blocks that show up in almost every large system, and say what each one does.
Describe four recurring concerns and identify other requirements the design must satisfy.
Tell a coding decision apart from a system design decision.
Say who does system design on a real team, and what the rest of this course covers.
You do not need any prior system design knowledge. If you have written a small program and used a website, you have enough background to follow along.
What system design means
System design is the work of choosing components, interfaces and data flows that meet a product’s requirements within its constraints. Those requirements include correct behavior, performance, reliability, security and cost. Large traffic volumes are one possible constraint; a small service handling sensitive or valuable data also needs a deliberate design.
Code implements these choices, and implementation feedback can change the design. A useful design describes the responsibilities of each component, how requests cross component boundaries, and how the system responds when dependencies fail or become slow.
An analogy helps. Think about the difference between cooking dinner for four people and running a restaurant kitchen on a Saturday night. Cooking for four is a recipe problem. Follow the steps and the dish comes out. Running the kitchen is a different problem entirely. How many cooks do you need? Who takes the orders, and how does each order reach the right station? What happens when two hundred orders arrive in the same ten minutes? What happens when the fryer breaks halfway through service? None of those questions is about how to cook a single dish. They are about the system.
Software is the same. A single feature, like "show the user their profile," is a recipe. System design is the kitchen.
In practice, a system design answers four kinds of questions:
Which parts exist. Every large system is built from a small number of recurring building blocks. You will meet them in a moment.
How the parts talk to each other. Which part calls which, in what order, and what they send back and forth. The agreed rules for how one part asks another for something are called an API, short for application programming interface. You will see that word constantly.
How the system behaves under stress. A million people arriving at once. A server dying. A slow connection between two data centers, the buildings where the servers live.
Which trade-offs we accept. Every choice gives something up. Faster responses may cost more money. Keeping data perfectly in sync everywhere may make the system slower. Design is choosing which costs you can live with.
The building blocks you will see everywhere
The same handful of terms will come up in nearly every lesson of this course, so here is a plain-language introduction to each one. Later lessons go deep on all of them.
| Building block | What it is | The restaurant version |
|---|---|---|
| Client | The app or browser the user is holding. It sends requests and shows results. | The customer at the table |
| Server | A computer that receives requests and does the work: runs the logic, looks up data, sends back a response. | A cook |
| Database | A service that stores and queries application data under defined transaction and recovery rules. | The pantry and the order book |
| Cache | A small, very fast copy of data that is read often, kept close to where it is needed so the database is not asked the same question a thousand times. | The prepped ingredients on the counter |
| Load balancer | A traffic director that routes requests across servers using a policy and health signals. | The host assigning tables |
| Queue | A waiting line for work that does not have to happen this instant. The system accepts the request now and finishes the work shortly after. | The ticket rail where orders wait for a free cook |
| Content delivery network (CDN) | Servers spread around the world that keep copies of files such as images and video close to users, so the file does not have to travel across the planet. | Satellite kitchens in each neighborhood |
You do not need to memorize this table. You need to recognize the words when they come up. By the end of the course they will feel familiar.
You will also hear the word service. A service is one part of the system that does one job, such as the login service or the search service, and it usually runs on its own set of servers.
Why system design matters
A small service may begin with one application and one database. That can be a sensible choice, but even a modest workload needs correct data handling, backups and clear failure behavior. More traffic exposes additional bottlenecks; restarting a process cannot repair every problem, especially lost or corrupted data.
The trouble starts when the software succeeds. An app that handles a thousand users comfortably does not usually handle a million. It is not that the same problems get a little bigger. New problems appear that did not exist before. One server cannot answer every request, and if that server dies, everything dies with it. Engineers call that a single point of failure. One database cannot hold everything or answer fast enough. Users in Tokyo get slow responses from a server in Virginia. Hardware fails, and once you have enough of it, something is always failing somewhere.
Teams without a deliberate design spend their weeks reacting: a slow page here, an outage there, a fix that breaks something else. A deliberate design does not remove failures. It decides in advance how the system will absorb them.
The four qualities a design has to deliver
This introduction focuses on four recurring concerns: scalability, availability, latency and consistency. They are useful starting points, alongside security, durability, maintainability and cost. Later lessons make each concern precise enough to test.
| Quality | The question it answers | What failure looks like |
|---|---|---|
| Scalability | Can the system handle a larger workload by adding or using resources effectively? | Response times or resource use grow beyond acceptable limits. |
| Availability | Is the system up and usable even when some part of it has broken? | An outage. One failed server takes the whole product down with it. |
| Low latency | Does the system respond quickly, wherever the user happens to be? | Spinners. Pages that take seconds to load. Video that buffers. |
| Consistency | Which values and orderings may clients observe as data changes? | Different readers may observe different versions outside the required model. |
Some guarantees require coordination, which can add latency across distant replicas. The actual trade-off depends on the operation and protocol. A ledger transfer and a delayed feed view have different requirements, while both still need appropriate authorization and data integrity.
Incident example: Google’s June 2019 network disruption affected services including YouTube and Gmail. Network congestion also slowed the recovery work. A design review should examine both how a configuration mistake can spread and whether recovery tools remain usable during the resulting failure. Google’s incident account describes that dependency.
What a designed system looks like
Enough abstraction. The diagram below shows a shape you will find, with small variations, behind most large web applications.
Let's follow one request through it. Say a user opens the app and asks for their home page.
The request leaves the user's phone (the client) and arrives at the load balancer.
The load balancer selects a web server using its configured routing policy. Health checks help remove failed servers from rotation, though detection takes time and requests already in progress may still fail.
The web server needs some data to build the page. It checks the cache first. If the data is there, the server gets it back almost instantly and skips the database entirely.
If the cache does not have it, the server goes to the database. New writes, such as the user posting something, go to the primary database, which then copies the change to the replicas. Reads can be served by the replicas, which keeps the primary from being swamped.
The server assembles the page and sends it back through the load balancer to the client.
Each component supports particular goals. Additional web servers can increase capacity and provide redundancy; a cache can reduce read latency; replicas can add read capacity and support recovery. None of these guarantees follows from drawing a box alone. The replication mode, health checks, failover procedure and application rules determine what happens to reads and writes during failure.
System design vs. coding
New engineers often hear "system design" and assume it means "hard coding." It does not. The two are different jobs, judged by different standards.
Coding is the work of making one part behave correctly. You write a function, handle the unusual inputs (the edge cases), write tests, and fix bugs. When your code is done, you can run it and watch it produce the right answer.
System design examines how components behave together under traffic, machine failures and delayed or lost messages. Review the design with estimates and failure scenarios, then test its assumptions through prototypes, load tests, integration tests and controlled rollout. A diagram is a model whose claims need evidence.
A concrete example makes the difference obvious. Take one small feature: the "like" button on a post.
A local implementation must validate the request, record the like, and update or derive the count. Even this code needs a concurrency rule: checking and then writing in separate uncoordinated steps can double-count a retried or concurrent action.
The same feature also raises questions across processes and storage systems:
Millions of likes arrive every minute. Where does the count live so that a thousand servers can update it without stepping on each other?
Two servers try to add one to the same count at the same instant. Does the count end up two higher, or one? That is a consistency question.
The post's author wants to see the count change right away. Do we show a number from the cache that might be a second old, or make every reader wait for the database? Latency against consistency again.
The server handling a like crashes after recording it but before updating the count. Is the like lost or counted twice? Section 5 covers failure and recovery mechanisms for this kind of partial completion.
Same button. Two very different sets of problems.
Here is the contrast side by side.
| Aspect | Coding | System design |
|---|---|---|
| Unit of work | A function, a class, a module | A service, a database, an API, and the connections between them |
| Typical task | Implement a feature, fix a bug, write tests | Decide where data lives, how services talk, what happens when a piece fails |
| What breaks | A wrong answer, a crash, an infinite loop | An outage, a slow page, data that disagrees with itself |
| How you check it | Run it and look at the output | Reason about it, estimate the load, review it with others, roll it out carefully |
| Success means | This part is correct | The whole product stays up, fast, and correct as it grows |
Coding and design develop together. Implementing a design reveals details that a diagram omitted; operating it exposes assumptions about load and failure. For interview practice, explain both the component responsibilities and the specific mechanism behind a guarantee, such as an atomic update that prevents a lost increment.
Interview tip: Start at the level requested by the prompt. Explain components, connections and failure behavior, then use a small code or data example when it helps make a critical mechanism precise.
Who does system design?
Design responsibilities depend on the team. The following roles often contribute different knowledge, and one person may fill several of them. Make decision ownership explicit so a reliability, product or security concern does not fall between teams.
Backend engineers design the services, the APIs those services expose, and the shape of the data. They usually own decisions about performance and about how data is stored.
Frontend engineers design the part the user touches. Their decisions, such as how much work the browser does versus the server, or how aggressively the app caches, change what the backend has to deliver and how fast the whole product feels.
Architects look at the whole system rather than one service. They set the overall structure and pick the core technologies, and they are usually the ones asked to sign off when a decision affects many teams.
Site reliability engineers (SREs) are the engineers who keep the system running in production, meaning the live version that real users depend on. They push for monitoring, alerts, automatic recovery, and plans for what to do when a data center goes dark, because they are the ones whose phone rings at 3 a.m. when it does.
Product managers and product-focused engineers bring the user's side. When a trade-off comes up, such as whether a feature can tolerate slightly out-of-date data, they know what users will and will not accept.
Note: In a team using a “you build it, you run it” model, service developers also share responsibility for production operation. That gives design discussions direct feedback from incidents and support work. Other teams divide these responsibilities differently.
One way teams make ownership explicit is a RACI chart. RACI stands for responsible, accountable, consulted, and informed. For each decision, it names who does the work (responsible), who makes the final call (accountable), who gets asked for input (consulted), and who only needs to hear the result (informed). The chart below shows how a typical team might split four common design decisions.
Read one row to see how it works. For API design, the backend engineer does the work, the architect has the final say, frontend and product are consulted because they will use the API and because it shapes the product, and the SRE is kept informed. For monitoring and alerts, the responsibility flips: the SRE owns it, backend and architect are consulted, and everyone else is informed. For user experience trade-offs, the frontend engineer does the work while product makes the final call, because the judgment about what users will accept belongs to product.
No role owns every decision. That is the point. Good designs come from people with different concerns arguing it out early, before the code is written.
Knowledge check
Four quick questions. Pick an answer, then read the explanation.
Knowledge check
Check your understanding
4 questions · source answers hidden
Who this course is for
This course starts with basic application concepts and develops the runtime, networking, storage, and failure models needed for architecture discussions. Use the exercises to check which assumptions you can explain clearly.
For interview preparation, use the course to practice stating assumptions, comparing designs and explaining failures. The final section applies those skills to an interview discussion. Check the format of the role you are applying for, since design expectations vary.
If you are an engineering manager or a product manager, the course will let you follow design discussions and push back on them with confidence. You do not have to build the systems to benefit from understanding why they are shaped the way they are.
And if you are aiming at an architect role, these fundamentals are the floor that everything else stands on. Advanced material assumes all of it.
How this course is organized
The course has nine sections. Each builds on the ones before it, so it is worth going in order, at least the first time through.
System design scope and architecture. Define requirements, choose a useful level of detail, and compare application boundaries.
Runtime resources and observability. Build a model of processes, threads, scheduling, memory, metrics, logs, and traces.
Networks, communication, APIs, and serialization. Follow messages between processes and compare interfaces and data contracts.
Time, ordering, coordination, and consistency. Reason about event order and shared decisions when machines communicate through a network.
Failures, availability, and recovery. Plan for crashes, uncertain outcomes, retries, and partitions using the runtime and network models already introduced.
Storage, databases, replication, and partitioning. Compare access patterns, transaction guarantees, indexes, replication, and data distribution.
Security and trust. Define who may read or change data and how identities, keys, and protected channels enforce those rules.
Scaling trade-offs, technology choices, and patterns. Match measured needs to caching, queues, replicas, shards, and operational patterns.
Interview preparation and next steps. Practice explaining a complete design and revising it when requirements change.
Key takeaways
System design is the plan for how the parts of a product fit together and keep working under real use. Code builds the parts. Design decides which parts exist and how they connect.
Almost every large system is built from the same handful of blocks: clients, servers, databases, caches, load balancers, queues, and content delivery networks.
Scalability, availability, latency, and consistency are useful starting concerns. Also identify security, durability, cost, and operational requirements.
Coding asks whether one part is correct. Design asks whether the whole product stays up, fast, and correct as it grows.
Design is a team activity. Backend, frontend, architecture, reliability, and product roles each own part of it.
The next lesson, How System Design Differs from Software Architecture, compares two useful views of a product: the organization of code within an application and the arrangement of services and infrastructure at runtime. The terminology overlaps in practice; the skill is choosing a useful level of detail and explaining how decisions cross those views.