Chapter 32 · Database sharding#
The big idea#
Sharding splits one big database into several smaller databases (shards), each holding a part of the data on its own machine. Together they hold everything; each handles only its share of the traffic.
Everyday example: a library with 10 million books in one room has one queue and one librarian. Split the books by author surname across 26 rooms (A, B, C…), each with its own librarian, and 26 people can be served at once. The rule “which room has this book?” is the shard key.
Why shard?#
A single database server eventually hits a ceiling:
Storage: the data no longer fits on one disk (tens of TB).
Write throughput: one primary can only commit so many writes per second.
Read throughput: replicas help reads, but not writes, and still hold the entire dataset.
Memory: the working set no longer fits in RAM, so every query touches disk.
Replication copies the same data; sharding splits different data. Large systems use both.
Shard late
Sharding is expensive: harder queries, harder transactions, harder operations. Try, in order: better indexes, caching, read replicas, bigger machine, archiving old data. Shard only when the numbers say so.
Choosing the shard key (the most important decision)#
A good shard key:
High cardinality: many distinct values (user_id, not country).
Even distribution: no value or shard gets most of the traffic.
Matches the main query: most queries include the key, so each touches one shard.
Rarely changes.
Product |
Good key |
Bad key |
Why |
|---|---|---|---|
Social app |
user_id |
country |
A few huge countries; uneven |
Multi-tenant SaaS |
tenant_id |
created_at |
New data piles on the newest shard |
Chat |
conversation_id |
message_id |
A chat’s messages stay together |
E-commerce orders |
customer_id |
order_status |
Status has only 4 values |
What gets harder#
Cross-shard queries and joins:
SELECT ... JOINacross shards must scatter-gather (ask all shards, merge results). Slow. Design so common queries hit one shard; keep small shared tables (countries, currencies) replicated to every shard.Transactions across shards: no simple ACID. Use sagas or two-phase commit (slow), or design so a transaction stays inside one shard.
Unique ids: auto-increment no longer works across shards. Use UUIDs, Snowflake-style ids, or per-shard ranges (see the unique IDs chapter).
Resharding: moving data when you add shards is the scariest operation. Plan for it: start with many logical shards (say 1,024) mapped to few physical machines; adding a machine means moving whole logical shards, never splitting rows.
Hot keys: one celebrity user gets millions of reads. Add caching, replicate that shard, or split that key.
Operations: backups, migrations and monitoring multiply by the number of shards.
Routing: who knows which shard?#
A routing layer (proxy such as Vitess or ProxySQL) hides sharding from the app.
A client library computes the shard from the key.
A coordinator/config service (ZooKeeper, etcd) holds the shard map.
Real examples#
Instagram sharded PostgreSQL by user using logical shards and embedded shard ids inside photo ids.
Vitess (YouTube) shards MySQL.
MongoDB, Cassandra, DynamoDB, CockroachDB shard automatically (partition by key).
Common mistakes#
Warning
Sharding too early.
A shard key that makes one shard hot (timestamps, auto-increment ids with range sharding).
Using
hash % Nand then being unable to add shards without moving 80% of the data.Designing queries that need to join across shards constantly.
Forgetting a plan for rebalancing.
Try it yourself#
An orders table of 20 TB with queries mostly “all orders of one customer”. Propose a shard key and a strategy.
Why is
hash(key) % Npainful when N changes?How do you handle a lookup table like “countries” that every query joins against?
Answers
Shard by customer_id with hash-based placement across many logical shards, so a customer’s orders stay together.
Changing N reassigns most keys (around 80% when going from 4 to 5), forcing massive data movement. Use consistent hashing or logical shards.
Replicate it to every shard (it is small and rarely changes), so joins stay local.
Next
Sharding splits data; replication copies it for safety and read capacity: replication.