Loading
Loading
Foundations
Scaling is not 'make it faster'. It is keeping a property constant while a number grows.
By the end of this chapter
People say a system scales as though it were a property of the code. It is not. Scaling is a claim with two halves, and a claim missing either half cannot be checked.
The first half is what grows: users, requests per second, stored bytes, concurrent connections, size of a single item. The second half is what must stay constant: response time, correctness, cost per request, operational effort.
Concept
A system scales along some dimension if you can grow that dimension by adding resources, without the properties you care about degrading and without the cost per unit rising.
Write it out for a real system and the vagueness disappears. "This service scales" becomes "this service can go from one thousand to one hundred thousand writes per second by adding API instances, keeping the ninety-ninth percentile under two hundred milliseconds, at roughly linear cost." That is a sentence somebody can disagree with, which is what makes it useful.
There are only two ways to give a system more resources, and they fail for different reasons.
| Vertical | Horizontal | |
|---|---|---|
| What you do | Bigger machine | More machines |
| Code changes | Usually none | Often substantial |
| Ceiling | The largest machine available | The part that cannot be split |
| Failure domain | One machine, all of it | One machine, a fraction of it |
| Cost curve | Superlinear at the top end | Roughly linear, plus coordination |
Vertical scaling is genuinely underrated. It requires no distributed systems, no partitioning scheme, no consensus, and a single large machine today is very large indeed. The reason it is not the end of the story is that its ceiling is fixed by what the market sells, and that one machine is a single failure domain: when it goes, everything goes.
Horizontal scaling removes that ceiling and replaces it with a harder question — what happens to the parts of the system that cannot simply be duplicated?
A system has one bottleneck at a time. Remove it and you do not get a system without a bottleneck; you get a system whose bottleneck is somewhere else.
Components (4): Client [client]; Load Balancer [load_balancer]; API Servers [api] — stateless, easy; Database [database] — the real limit Connections (3): Client -> Load Balancer; Load Balancer -> API Servers; API Servers -> Database Legend: -> synchronous, ~> asynchronous, => replication.
This is why the honest answer to "how would you scale this?" is a sequence rather than an architecture. First the web tier saturates and you add instances. Then the database's connection count saturates and you pool. Then read throughput saturates and you add replicas. Then write throughput saturates, and now you are partitioning, which is a different kind of problem with a different kind of cost.
Sign in to keep a note here. It is free, and nobody else can see it.
Sign inWhat this chapter was for: