Fundamentals
The scale cube
Three independent ways to split a system, by cloning, by function and by data, and how to name the next step in a design review.
The scale cube, from Martin Abbott and Michael Fisher's The Art of Scalability, names three independent ways to split a system. Each axis solves a different problem. Naming the axis tells you what a change will buy and what it will cost.
The big idea
Picture a cube with three directions. Moving along one axis does not require moving along the others. You can clone a service without splitting it, or shard data without splitting the code.
| Axis | What you split | Example | What it buys |
|---|---|---|---|
| X: clone | Run identical copies behind a load balancer | 20 stateless API servers, or read replicas | More throughput for the same work. Every copy still holds all the data |
| Y: function | Split by function or service | Separate checkout, search and recommendations | Teams and components scale on their own. See microservices |
| Z: data | Split by customer, key or region | Users A to M on shard 1, N to Z on shard 2 | Each node holds part of the data. Writes and storage scale |
The limit of each axis matters. Cloning does not help write-heavy workloads, because every copy still has to apply every write. Splitting by function does not help if one database still holds everything.
Walking through it
Take a marketplace whose order database is maxed out.
- X first. Stateless API servers are cloned to handle more requests. The database is not helped, because every clone still sends its writes to the same primary.
- Y next. Checkout is split out, so its load and deploys are separate from search. The order database is still shared.
- Z last. The order database is sharded by merchant ID. Each shard holds a part of the orders, and the writes spread across shards.
In a design review, the sentence becomes: "We have exhausted X for the orders database. The next step is Z, by merchant ID."
Most large systems use all three axes. A common pattern splits by function into a few services, clones each service, and shards the largest data stores.
Common mistakes
- Cloning to fix a write bottleneck. Writes still go to one primary.
- Splitting services before splitting data. Services that share one database are still coupled.
- Sharding by an arbitrary key. Pick a key that matches the access pattern, such as merchant ID for orders.
Check yourself
-
Which axis helps a write-heavy database that is already at its limit?
Answer: Z, data partitioning. Cloning (X) gives every copy all the data, so writes do not spread.
-
Where do read replicas fit on the cube?
Answer: on the X axis. They are clones of the same data.
Key takeaways
- The scale cube names three independent ways to split a system: clone, split by function, split by data.
- Each axis solves a different bottleneck and has a different limit.
- Cloning does not reduce writes, so write-heavy systems need data partitioning.
Further learning
Next, see how to find the bottleneck that these splits are meant to fix, in finding the bottleneck.
Related
Scaling fundamentals
Vertical versus horizontal scaling, stateless services, the usual order in which a growing system adds parts, and how to find the real bottleneck. Start here for the scaling map.
Monoliths and microservices
When to split a system, how to draw service boundaries, and the operational cost that microservices add.
Sharding and partitioning
Split data across machines by choosing a shard key, hashing or ranging it, routing requests, handling hot spots, resharding without downtime and generating IDs that stay unique.
Load balancing and proxies
How a load balancer chooses which server gets each request, and how a badly set up balancer can cause the outage it was meant to prevent.