Back to System design

Sharding Strategies: Range, Hash, Directory, Geo

medium
Scale: Linear scale with shard count; cross-shard ops cost more Storage: Distributed across N shards + per-shard replicas Meta, Twitter, Uber
FundamentalsDatabasesSharding

Sharding 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.