Software Engineering · Deep dive

Designing for Scale

How a backend service goes from one box to millions of requests a day without falling over. The laws that bound every system, the levers in the order you reach for them, and the trade-off hiding behind each one — worked through a single running example: Snip, a URL shortener with click analytics.

Find the bottleneck, then move itclientloadbalancerappDBbottlenecktwo movesscale upbiggerboxmore CPU / RAM · simple · has a ceilingscale outmore boxes · split the datashard / replicate

Scaling is not a feature you add; it is a sequence of bottlenecks you remove. Every system has one resource it runs out of first — a CPU, a disk, a lock, a single database — and the craft is finding that resource, then either making it bigger (scale up) or spreading the work across more of them (scale out). Do that, and a new bottleneck appears behind it. The whole discipline is this loop, run with judgement about which move is worth its cost.

This guide builds the toolkit from first principles. It assumes you can write a service and query a database, but not that you have run one under real load. Each chapter adds one lever — caching, replication, sharding, queues — explains the mechanism and the price, and shows where it applies to Snip. The last chapter puts every lever together on one whiteboard.

How to read this guide

Chapters build in order, each adding one lever to the toolkit, so a first read front to back pays off. If you are short on time, pick a path:

New to backend scale

Read 00 → 04 in order; that is the core — the laws, statelessness, caching, and the database. Then read 08 (tail latency) and 09 (reliability). Come back for 05–07 when you hit them.

Engineer brushing up

Skim 01, read 03, 04 and 05 closely (caching, sharding, consistency), then 06 and 08. Chapter 10 ties it together.

System-design interview soon

00, 01 (the numbers), 04, 05, 08, then 10 as a dry run. 09 for the reliability questions interviewers add at the end.