Sharding and Shard Keys
What Sharding Is
Sharding means splitting your data across several database servers, so no single server holds everything. Each piece is a shard: a standalone database with its own CPU, memory, and disk, holding only part of the data. Together, the shards hold the full dataset.
Think of a library that outgrew its building. Instead of one giant building, you open branches, and each branch keeps only some of the books. Each branch is smaller, and visitors are spread across them.
1Before After (sharded by user_id)2App → [ one DB: all orders ] App → Router ─┬→ [ Shard 1: some users' orders ]3 ├→ [ Shard 2: some users' orders ]4 └→ [ Shard 3: some users' orders ]Replication copies the same data to more servers, which scales reads. Sharding splits the data, which scales writes and storage. Each shard is usually also a small replica set, so it has failover too.
Do You Even Need It?
Sharding comes last, after a bigger server, good indexes, caching, and read replicas. Justify it with numbers:
1Orders: 5 million/day × 1 KB = 5 GB/day ≈ 1.8 TB/year → one big server, for now2Writes: 2,000 orders/sec × 5 writes = 10,000 writes/sec → near one server's limit3 4Grow 10× → ~18 TB/year and 100,000 writes/sec → shardSaying "we don't need to shard yet, here's the math" is a strong interview answer.
The Two Decisions
Every sharding design answers two questions:
- What do we shard by? → the shard key, the field that groups data.
- How do we place key values on shards? → the distribution strategy: range or hash.
1order { user_id: 42, ... }2 │3 shard key = user_id4 │5 distribution: hash(42) → shard 2Decision 1: Choosing a Shard Key
A good shard key has three properties:
| Property | Meaning | Why it matters |
|---|---|---|
| High cardinality | Many distinct values | Data can spread across many shards |
| Even distribution | Values and traffic spread evenly | No shard takes most of the load |
| Query alignment | Present in your most common queries | A common query hits one shard |
For our orders:
| Shard key | Verdict | Why |
|---|---|---|
user_id | Good | Millions of users, evenly spread, and "My Orders" hits one shard |
order_id | OK | Good spread, but "My Orders" would hit every shard |
city | Bad | Few values, and one big city overloads its shard |
is_veg | Bad | Only 2 values, so at most 2 shards |
created_at | Bad | All new orders land on the newest shard |
The shard key is very hard to change later. MongoDB can reshard a collection, but it copies the whole collection, so pick carefully up front.
Decision 2: Range vs Hashed Sharding
Range sharding splits the key into continuous ranges, like a dictionary split into volumes A–H, I–P, Q–Z.
Hashed sharding runs the key through a hash function (a formula that turns any value into a scrambled number) and uses that number to pick a shard. Neighbouring keys land on different shards.
1Range (by user_id) Hashed (by hash(user_id))2Shard 1: 1 – 10M user 41 → Shard 33Shard 2: 10M – 20M user 42 → Shard 14Shard 3: 20M – 30M ← all new users user 43 → Shard 2 ← neighbours scattered| Range | Hashed | |
|---|---|---|
| Data spread | Can be uneven | Even |
| Increasing keys (ids, timestamps) | All new writes hit the last shard: a hot shard | Writes spread evenly |
Range query on the shard key (user_id BETWEEN 100 AND 200) | Hits one or a few shards | Hits all shards |
Exact match (user_id = 42) | One shard | One shard |
| Choose when | Range queries matter and keys are not ever-increasing | Even spread matters most (the usual default) |
Growing a hashed setup. Plain hash(key) % number_of_shards moves most data when you add a shard:
13 shards → 4 shards: hash % 3 becomes hash % 42→ about 3 out of 4 keys move to a different shardConsistent hashing places keys and shards on a ring; each key goes to the next shard along the ring. Adding a fourth shard moves only about a quarter of the keys. Hash + consistent hashing is the usual default, and interviewers assume it when you say "shard by user_id".
A third option, directory sharding, keeps a lookup table of which key lives on which shard. It's flexible but adds an extra lookup per request and a single point of failure, so use it only for special cases.
sh.enableSharding("food");// hashed: even spreadsh.shardCollection("food.orders", { userId: "hashed" });// range: good for range queries on the key// sh.shardCollection("food.orders", { userId: 1 });
Problems Sharding Creates
| Problem | Example | Fixes |
|---|---|---|
| Hot shard | Shard by restaurant_id, one hugely popular restaurant during a sale | Compound key (restaurant_id + bucket 0–9) to spread it; or a dedicated shard for very busy keys |
| Cross-shard query | Sharded by user_id, but "today's orders for restaurant 7" must ask every shard and merge (scatter-gather) | Better shard key; cache the result; denormalize into a copy sharded by restaurant_id |
| Cross-shard transaction | Wallet transfer between two users on different shards | Keep related data on one shard; saga (steps with undo actions); 2PC (correct but slow and fragile) |
1Saga: wallet transfer, user A (shard 1) → user B (shard 3)2Step 1: deduct ₹200 from A ✓3Step 2: add ₹200 to B ✗ fails4Undo: refund ₹200 to A ✓ → back to a correct stateIf a common query keeps hitting every shard, the shard key is probably wrong.
Interview Angle
How to Explain it in an Interview
Common mistakes:
- Sharding by reflex, without showing that one server isn't enough.
- Picking a timestamp or auto-increment id with range sharding.
- Not naming the shard key explicitly, with a reason.
Summary
1Sharding → split data across servers → scales writes + storage2Need it? → only when the math says one server can't keep up3Shard key → high cardinality + even spread + matches main queries4Range → good for range queries, hot shard on increasing keys5Hashed → even spread, range queries hit all shards6Default → hash + consistent hashing7Problems → hot shard, cross-shard queries, cross-shard transactionsWith data spread over many servers, network failures between them are unavoidable. Next, the CAP theorem explains what a distributed database must give up when that happens.