Systems design is the art of arranging servers, databases, caches, and networks into an architecture that stays fast, correct, and available as it grows from a hundred users to a hundred million. Where the earlier parts of this book asked "how does one machine work?", this part asks "how do many machines work together?" — and the answer is a small vocabulary of building blocks that recur in every large system.
Every design is judged against four properties, and they constantly trade off against one another:
- Scalable — handles growth in users and data without a rewrite.
- Reliable — keeps working correctly even when components fail.
- Available — responds to requests, even under load or partial failure.
- Maintainable — easy to understand, change, and operate.
Scalability — Up vs Out
There are only two ways to handle more load: get a bigger machine, or get more machines.
Vertical scaling (a bigger box) is simple — no code changes — but it hits a hard ceiling and leaves you with a single point of failure. Horizontal scaling (more boxes) is effectively unlimited and more resilient, but it forces you to confront the central challenge of this entire part: coordinating state across machines. Almost everything that follows exists to make horizontal scaling work.
Load Balancing
The instant you have more than one server, something must decide which one handles each request. That's a load balancer — it spreads incoming traffic across a pool of identical servers, and reroutes around any that fail.
It chooses a server using one of a few algorithms:
| Algorithm | How it works |
|---|---|
| Round robin | Cycle through servers in order |
| Least connections | Send to the server with the fewest active connections |
| IP hash | Hash the client IP → same client always hits the same server (session stickiness) |
| Weighted | Bigger servers receive proportionally more traffic |
Analogy: A load balancer is the host at a restaurant, seating arriving guests across tables so no single waiter is overwhelmed — and skipping any table that's out of service.
Caching
A cache stores frequently used data somewhere faster than the source — usually memory instead of disk or network. It's the highest-leverage performance tool in systems design.
Caching can happen at every layer of a stack:
- Client-side — browser and mobile app caches
- CDN — static content served from near the user (below)
- Application — Redis or Memcached holding hot objects
- Database — query cache and buffer pool
The hard part isn't storing data — it's knowing when the cached copy is stale. The strategy you pick is a trade between speed and freshness:
| Strategy | How it works | Trade-off |
|---|---|---|
| Write-through | Write to cache and DB together | Slower writes, always consistent |
| Write-behind | Write to cache, flush to DB async | Fast writes, risk of loss on crash |
| Cache-aside | App reads cache, falls back to DB on miss | Most common, risk of stale reads |
| TTL | Entries expire after N seconds | Simple, eventually consistent |
Phil Karlton: "There are only two hard things in Computer Science: cache invalidation and naming things."
Analogy: A cache is a cheat sheet of formulas you keep handy during an exam. You glance at it instead of re-deriving each time — but if a formula changes and you don't update the sheet, you'll confidently write the wrong answer (a stale cache).
CDN — Content Delivery Network
A CDN is caching applied to geography. It's a fleet of servers spread across the globe that cache static content (images, CSS, JS, video) and serve it from an edge location physically close to each user. Since latency is bounded by the speed of light, distance is destiny:
Analogy: A CDN is a restaurant franchise. Instead of every customer flying to the one original location in New York, there's a branch in every city serving the same menu.
Proxies
A proxy is an intermediary that requests pass through — and which way it faces changes everything.
Analogy: A forward proxy is a lawyer speaking on your behalf, hiding your identity from the other side. A reverse proxy is a company receptionist — clients talk to reception, never to individual employees, who stay hidden behind it.
A load balancer is one kind of reverse proxy; so is the TLS-terminating, caching front door (Nginx, Cloudflare) that sits before nearly every production web service.
Message Queues — Asynchronous Communication
When one service calls another directly and waits for the reply, the two are tightly coupled: if the callee is slow or down, the caller is stuck. A message queue breaks that coupling by letting services communicate through an intermediary.
Decoupling through a queue buys you four things: services don't need to know about each other, the queue buffers traffic spikes, messages persist if the consumer is temporarily down, and you can scale throughput by adding more consumers.
Analogy: A queue is a mailbox. The sender drops a letter and walks away; the carrier picks it up whenever ready. Neither has to be present at the same moment.
Kafka deserves a special mention because it's more than a queue — it's a distributed, append-only commit log. Messages are ordered, durably stored, and replayable, and different consumers can read from different positions independently.
Analogy: A plain queue is a bakery line — once you're served, you're gone. Kafka is a newspaper archive — new issues are appended, old issues stay readable, and every reader can be at a different point in the archive.