Do you need sharding yet?
Shard when a single replica set can't hold the data or handle the write throughput even after indexing and vertical scaling (see the WiredTiger cache post). Sharding adds operational complexity.
Properties of a good shard key
| Property | Why | Bad example |
|---|---|---|
| High cardinality | Enough distinct values to split into many chunks | status (few values) |
| Low frequency | No single value holds a big share of documents | country when 70% are one country |
| Non-monotonic (for inserts) | Inserts spread across shards | createdAt or ObjectId alone → all inserts to one shard |
| Matches query patterns | Targeted queries hit one shard; otherwise scatter-gather | Key not in common filters |
Patterns
| Pattern | Example | Notes |
|---|---|---|
| Compound key | { customerId: 1, orderDate: 1 } | Groups a customer's data; range queries by date within customer |
| Hashed key | { deviceId: "hashed" } | Even distribution; range queries on that field become scatter-gather |
| Compound with hashed prefix | { tenantId: "hashed", ts: 1 } | Spread tenants, keep time order within tenant |
| Zone sharding | Ranges of key pinned to shards in regions | Data residency, locality |
sh.shardCollection("shop.orders", { customerId: 1, orderDate: 1 })
sh.shardCollection("iot.readings", { deviceId: "hashed" })
Analyse before choosing
- List the top queries and updates; each should include the shard key prefix to be targeted.
- Check value distribution:
db.orders.aggregate([
{ $group: { _id: "$customerId", n: { $sum: 1 } } },
{ $sort: { n: -1 } }, { $limit: 10 }
])
- Newer versions provide
analyzeShardKeyto score candidates on cardinality, frequency and query targeting; use it on a copy or with sampling.
After sharding
- Watch chunk/range distribution and balancer activity:
sh.status(). - Watch for jumbo chunks (a single key value too large to split).
- Monitor scatter-gather queries in logs/profiler.
Changing your mind
reshardCollection (5.0+) can change the key online but needs extra capacity and time for large collections. You can also refine a key by adding suffix fields (refineCollectionShardKey). Plan for it, but aim to get the key right first.
Warning
Sharding on a monotonically increasing field (timestamps, ObjectId) alone sends every insert to the same shard. It's the most common shard key mistake.
Checklist
- Sharding actually needed
- Top queries include the candidate key
- Cardinality, frequency and monotonicity checked
- Compound/hashed/zone pattern chosen
- Distribution and scatter-gather monitored
- Resharding plan understood