Writing a feature answers "what should happen when someone presses this button?". System design answers the questions around it: where does the data live, how many machines run the code, what happens when one of them breaks, and how does it stay fast when ten times more people show up?
It's the difference between a recipe and running a restaurant. The recipe is the code. The restaurant is the kitchen layout, how many cooks you hire, where the fridge goes, and what you do when the oven breaks on a Friday night.
The building blocks
Most large systems are built from the same handful of parts, arranged differently:
- Clients: the apps and browsers people use.
- Load balancer: spreads incoming requests over several servers, so no single one is swamped.
- App servers: run your code. Usually several identical copies.
- Database: the long-term memory. The source of truth.
- Cache: a small, fast copy of popular data, so the database isn't asked the same thing over and over.
- Queue and workers: slow jobs (sending emails, resizing photos) are put in a queue and done in the background, so the user doesn't wait.
This course takes each block apart: how it works, when to use it, and what it costs.
Everything is a trade-off
There is no "best" design, only designs that fit a situation. Adding a cache makes reads faster, but now you have two copies of the data that can disagree. Adding servers handles more traffic, but now they have to coordinate. Keeping one copy of the data is simple, but if that machine dies, you're down.
A good design names its trade-offs out loud: "We accept that a 'like' count may be a few seconds out of date, because it lets us serve the page from cache." That sentence is worth more than any diagram.
Key idea: system design is choosing and arranging the parts around your code (servers, storage, caches, queues) so the whole thing stays fast, available and correct as it grows. Every choice trades something for something else.