Back to System design
Sharding Strategies: Range, Hash, Directory, Geo
mediumSharding means splitting one database into several, each holding part of the data. You do it when one machine can no longer hold everything, or can no longer keep up with the writes.
ScaleLinear scale with shard count; cross-shard ops cost more
StorageDistributed across N shards + per-shard replicas
Key Concepts
1
The hard part is choosing which rows go where, because that choice decides which queries stay fast and
which become impossible.
which rows go where
2
Range sharding gives each machine a slice of the keys: customers A to F here, G to M there. Queries
for a range — "all orders in March" — stay on one machine, which is exactly what you want for reports.
Range sharding
3
It has one bad failure. If you shard by date or by an ever-increasing ID, every new row lands on the last
machine. You now have all the complexity of sharding and still one machine doing the writing.
4
Hash sharding decides by a hash of the key, so rows spread evenly and no machine becomes a hotspot.
The price is range queries: "all orders in March" now has to ask every machine and merge the answers, and
that gets slower as you add machines.
Hash sharding
5
Directory sharding keeps a lookup table saying where each key lives. It is the most flexible — you can
move one noisy customer to their own machine without touching anyone else. The costs are an extra lookup on
every request and a table that must never be unavailable.
Directory sharding
6
Geo sharding keeps data near its users, which helps latency and is often a legal requirement. Queries
that cross regions get slow, and a user who moves country needs their data moved.
Geo sharding
7
The question behind the question is what happens when you add machines. Ten shards become twenty.
The question behind the question is what happens when you add machines.
8
With plain modulo hashing, nearly every key moves. With consistent hashing, about one shard's worth moves.
Better still, split the data into many more logical pieces than you have machines — say 1,024 pieces across
10 machines. Adding machines then means reassigning pieces, which you can do one at a time, online.
Mentioning that unprompted is usually what marks a senior answer.
9
Cross-shard work is the tax you pay. A join across shards means fetching from several and combining in
the application. A transaction across shards is slow and fragile. So the real skill is choosing a key that
keeps related rows together — everything about one customer on one shard — so most queries never cross.
Cross-shard work is the tax you pay.
10
What the interviewer is probing.
What the interviewer is probing.
11
1. "The database is too big. What do you do?" Probing: whether you try cheaper things first.
Stalls: sharding immediately. Moves up: read replicas, archiving old data, a bigger machine — then
shard when the writes or the size genuinely exceed one box.
1. "The database is too big. What do you do?"
12
2. "What is your shard key?" Probing: whether the key follows the queries. Stalls: "The primary
key." Moves up: the key that keeps related rows together and spreads load, and naming which queries it
makes expensive.
2. "What is your shard key?"
13
3. "You shard by created_at." Probing: the hotspot. Stalls: accepting it. Moves up: every insert
lands on the newest shard; add a hashed prefix to spread writes.
3. "You shard by created_at."
14
4. "One customer is 40% of your traffic." Probing: skew. Stalls: "Add more shards." Moves up:
that customer needs their own, which means a directory-style exception on top of hashing.
4. "One customer is 40% of your traffic."
15
5. "How do you go from 10 shards to 20?" Probing: whether resharding was planned for. Stalls:
"Migrate the data." Moves up: modulo moves almost everything, the ring moves a fraction, pre-split
pieces make it a config change done one piece at a time.
5. "How do you go from 10 shards to 20?"
Components
- Shard map service / metadata store (etcd, ZooKeeper, custom).
- Routing layer — in-client library or proxy (Vitess vtgate, ProxySQL).
- Per-shard replica set for HA (3-5 replicas).
- Rebalancer / splitter — splits hot shards, merges cold ones.
- Backup / restore per shard; coordinated PITR across shards.
- Cross-shard query layer if unavoidable (scatter-gather with merge).
- Monitoring per shard — load, latency, replica lag, hot key detection.
Resharding cost, worked
Keys 1,000,000,000 Shards before 10 Shards after 20
Plain modulo (hash % N)
A key moves unless hash % 10 == hash % 20, which holds for
about half the keys here.
Keys moved ~500,000,000 (50%)
At 50,000 keys/s of migration ~2.8 hours of copying
(and it is 90%+ when going from 10 to 11) Consistent hashing
Keys moved ~1/N of the ring ~50,000,000 (5%)
At 50,000 keys/s ~17 minutes Pre-split logical shards (1,024 logical -> N physical)
Keys moved: only the logical shards being reassigned.
10 -> 20 physical means moving ~512 logical shards' worth of
data, but the mapping change itself is a config update, and the
move can be done shard by shard, online, with no rehash. Why the last option wins in practice
The data still moves, but the unit of movement is a logical shard
you can copy, verify and cut over one at a time. Failure affects
1/1024 of the keyspace, not the whole migration.Choosing by access pattern
Workload Strategy Why
-------------------------------------------------------------------
Key-value by user id Hash Even spread, all
lookups single-shard Time-range analytics Range Scans stay local;
accept write hotspot
or add a hashed prefix Multi-tenant SaaS Hash + directory Hash by tenant, with
directory exceptions
for the giants Global consumer app Geo Latency and data
residency; migrate on
user relocation Social graph Hash by user Keeps a user's data
+ denormalise together; fan-out
handled at write time The test for a shard key
1. Does one shard's worth of traffic fit on one node?
2. Do your three most common queries hit one shard?
3. Can the key never change? (A changing shard key is a data move.)
If any answer is no, the key is wrong, not the strategy.Failure modes in production
Monotonic key hotspot
Symptom: the newest shard is at 100% while the rest idle.
Cause: sharding on time or auto-increment id.
Fix: hash prefix, or bucket by (hash(user) , time) so writes spread
while ranges stay mostly local.
Cross-shard transaction creep
Symptom: latency grows and deadlocks appear as features are added.
Cause: a shard key that no longer matches how the app writes.
Fix: revisit the key; denormalise so a write touches one shard; use a
saga where it genuinely cannot. Directory unavailable
Symptom: total outage despite every data shard being healthy.
Cause: the lookup table treated as a normal service.
Fix: replicate it, cache it in every client with a long TTL, and make
a stale entry survivable -- a wrong shard should return "not mine",
not an error. Silent skew after growth
Symptom: one shard grows twice as fast; nobody notices for a quarter.
Cause: no per-shard size and traffic dashboard.
Fix: alert on shard imbalance ratio, not just total size.