6. Vertical vs Horizontal Scaling
6.7 What about the database? Why is it the hardest part to scale?
In the kitchen: You can hire twenty chefs, but they all fetch ingredients from one pantry through one door. At some point the pantry, not the chefs, is the bottleneck. And unlike chefs, you can't simply clone the pantry: if two copies disagree about how much rice is left, someone cooks with rice that isn't there.
In the system: App servers scale out easily because they hold no state. The database is the opposite: it is the state. Making more copies means keeping them in sync (Chapter 14), and splitting the data means deciding who holds what (Chapter 15). So when you scale out the app tier, the load lands on the database.
Climb the ladder one step at a time, cheapest first:
Figure: each step up adds cost and complexity. Most systems never need the top step.
- Fix the queries: add the missing index, stop fetching rows you don't need, remove repeated queries (Chapter 9).
- Add a cache for repeated reads (Chapter 12).
- Scale up the database machine. Often the simplest big win.
- Read replicas: copies that serve reads, while the primary handles writes (Chapter 14).
- Shard: split the data across several databases, each owning part of it (Chapter 15). Powerful, but it changes how every query works.
Also watch connections: 67 app servers with 50 database connections each is 3,350 connections, more than many databases handle well. A connection pooler in front of the database helps.
Memory code: "Fix, cache, grow, copy, split." In that order.