Networking: What happens when you open a web page
You type an address, press enter, and a page appears a fraction of a second later. In that fraction of a second a request leaves your device, crosses your home, your city, and possibly an ocean, finds one specific machine out of the billions on the internet, and comes back with an answer. Almost everyone who builds software relies on this happening and can't actually trace it end to end.
APIs: How services talk to each other
The previous lesson ended at HTTP — the envelope a request travels in. But HTTP only says how to package a request and a response; it says nothing about what any particular request means. You can speak HTTP flawlessly, send a perfectly valid GET /user/42, and still get nothing useful back, because the server was never told that /user/42 is a thing anyone can ask for.
Load balancing: Spreading the load
One server has a ceiling. Enough traffic, and it runs out of CPU, memory, or connections, and requests start to queue or fail. There are only two ways out, and the second one creates the problem this lesson is about.
Latency & resilience: Distance and failure
The earlier lessons quietly assumed the network just works: the request goes out, the response comes back. Across a real internet it doesn't, for two physical reasons. Distance is one — signals take time to cross the planet, and that time is latency the user feels. Failure is the other — links and machines go down. This lesson is the defensive toolkit for both, plus the second-order problem that failure creates when it spreads.
Databases: Where data lives
Once a request reaches a server, it almost always needs to read or write data — and "the database" is not one thing. Before picking one you answer three questions in order: what guarantees do you need when data changes (ACID), how should the data be shaped (normalized or not), and which family of store fits the way you'll actually read and write it. The last question is really a choice of trade-offs, which is why there are so many kinds.
Caching: Not doing the work twice
The fastest work is the work you never do. A cache stores the result of something expensive — a database query, a computation, a fetch from far away — so the next request for it gets the answer immediately instead of paying the full cost again. That's the whole idea, and it's one of the highest-leverage moves in system design.
Indexing: Finding the needle
Without an index, finding a row means reading every row — the database scans the whole table, start to finish, and throws away everything that doesn't match. That's fine for a hundred rows and ruinous for a hundred million.
Sharding: Splitting the data
Spreading the load solved too much traffic by adding more servers. This lesson is the same move for too much data. A single database has a ceiling just like a single server does first inside one database (partitioning), then across many (sharding). The rest of the lesson is how you split, and what splitting breaks.
Consistent hashing: The hash ring
Splitting the data ended on a cliffhanger. Hash-based sharding spreads data beautifully — until you add or remove a shard, and shard = hash(key) % N reshuffles almost everything, because N changed. For a system that's growing, that's a dealbreaker: every time you add capacity, nearly all your data has to move at once. Consistent hashing is the fix — a different way to map keys to shards that moves only a thin slice of the data when the shard count changes.
CAP theorem: When the network splits
Every distributed system in this arc — the sharded database, the replicated cache, the hash ring — is many machines pretending to be one. The CAP theorem is the law that says how far that pretence can go. It's short, famous, and the thing interviewers reach for to check whether you really understand the deepest trade-off in distributed systems. This lesson is what it actually says, and how to use it.