Sharding and consistent hashing
Sharding splits one database across several servers, so each server holds part of the rows and takes part of the writes. It is the most powerful scaling tool in this course, and the most expensive one to live with. This lesson shows when you really need it and how the routing works.
By the end you can
- List what to try before sharding, in order
- Choose a shard key and predict hot shards and cross-shard queries
- Explain why "hash mod N" moves most keys when you add a server, and how consistent hashing moves about 1/N
- Build a consistent hash ring with virtual nodes in TypeScript
- Distribute a Postgres table across servers with Citus
The everyday picture
Mangrove Market once had one distribution centre (DC) that held stock for every store. The chain grew, and the DC ran out of floor space and loading bays. So the company opened three DCs: North, East and South. Each one holds stock for a group of stores.
Now every order needs a rule: "Store 27 is served by the East DC". A truck driver who guesses wrong drives to the wrong DC. Some questions get harder too. "How many cartons of milk do we have in total?" now means calling three DCs and adding up the answers.
The hardest moment is opening a fourth DC. If the rule is "store number mod 3", changing it to "mod 4" moves most stores to a different DC overnight, with trucks full of stock going everywhere. A better rule moves only the stores the new DC really needs to take. That better rule is consistent hashing.
Try everything else first
Sharding means each server, called a shard, holds only some of the rows. It is the only tool here that adds write capacity, because writes for different keys go to different machines. It also turns one database into several, and every query, migration, backup and incident gets harder. So it comes last. Work down this list, and measure after each step:
- Fix the queries and indexes. One missing index can cost more than all your traffic growth (Indexes from the inside, Reading query plans and fixing slow queries).
- Cache hot reads in Redis (Caching).
- Move reads to replicas, especially reports and dashboards (Replication and read replicas).
- Pool connections and tune the server (Running Postgres in production).
- Partition the big tables so maintenance and date queries stay fast (Partitioning big tables).
- Buy a bigger machine. Cloud servers with 64 or more cores and hundreds of GB of RAM are ordinary today. That is often cheaper than a month of engineering time.
- Move work off the database: queues for slow jobs (Queues, background jobs and pub/sub), a warehouse for analytics (Beyond SQL: choosing the right data store).
Shard when one primary cannot take the write load even on the biggest machine you can buy, or when the data set is too big for one server's disk and the time it takes to back it up and restore it. Most retail systems never reach this point. In Speed numbers and back-of-the-envelope math, the till uploads from every Mangrove store came to about 74 rows per second at peak, which one Postgres server handles easily.
There is also a lighter step called a vertical split: move a whole feature to its own database, such as loyalty points on one server and sales on another. No table is cut in half, so no routing rule is needed. The price is that you can no longer join or use one transaction across the two. Sharding a single table across servers is called horizontal sharding, and the rest of this lesson is about that.
Quick check
Which problem is sharding the right answer to?
Sharding is the only tool here that adds write capacity, so it fits a measured write limit. Slow reports and big history call for partitioning and a replica or warehouse, dashboards belong on a replica, and a missing index is fixed with an index.