Choosing a MongoDB Shard Key: Ranged, Hashed, and Composite
Pick a MongoDB shard key that matches your query pattern, avoids write hotspots, and supports efficient range scans.
06 Dec 2025, 21:13 UTC

The decision: pick a shard key before you shard
When you shard a MongoDB collection, every document is routed to a shard based on the shard key you define. That choice is effectively permanent: MongoDB does not let you change a shard key in place. In MongoDB 5.0 and later, resharding can replace the key, but it is an operational project, not a configuration toggle. Pick poorly and you face write hotspots, scatter-gather queries that hit every shard, or jumbo chunks that cannot be split.
Useful takeaway: choose a shard key that matches your most common query pattern, has high cardinality, and avoids monotonically increasing values if you use a ranged key.
Constraints to check first
- Shard from a
mongosrouter connected to a sharded cluster, not directly from amongod. - The collection must be empty or already sharded; you cannot attach a shard key to an existing unsharded collection without sharding it first.
- Shard key fields should be supported by an index after sharding.
- Shard key values cannot be changed for existing documents after sharding begins.
Supported shard key types
| Type | How it routes data | Best for | Main risk |
|---|---|---|---|
| Ranged | Documents with similar key values live on the same shard; chunks split by key ranges. | Range queries and sorted reads on the key. | Write hotspots on increasing keys such as timestamps or ObjectId. |
| Hashed | A hash of the key value determines the shard, spreading writes evenly. | High-write workloads with equality lookups. | Range queries scatter-gather across all shards. |
| Composite | Multiple fields form the key; a high-cardinality prefix spreads writes, suffix fields improve query targeting. | Mixed read/write workloads needing both distribution and query isolation. | More complex to design; queries must include the prefix to target a single shard efficiently. |
Trade-offs in practice
Ranged keys: locality at the cost of hotspots
A ranged shard key keeps related data together. If your application reads recent orders by date, a ranged key on order_date lets MongoDB route that query to the shards holding those dates. The downside appears when the key increases over time. All new inserts fall into the current maximum chunk, so one shard absorbs the write load while others sit idle.
Hashed keys: even writes, expensive ranges
Hashed keys randomize placement, which eliminates insert hotspots. However, MongoDB cannot use the hash to satisfy a range query. A query like { created_at: { $gt: ..., $lt: ... } } on a hashed key broadcasts to every shard. Use hashed keys when writes dominate and equality lookups provide the full key value.
Composite keys: balancing distribution and targeting
A composite key such as { tenant_id: 1, created_at: 1 } uses tenant_id to spread tenants across shards and created_at to order data within a tenant. Queries that include tenant_id can target one shard; queries omitting it may scatter-gather. Choose a high-cardinality prefix so no single prefix value dominates a shard.
Concrete implementation: sharding a collection
Run the following in mongosh connected to a mongos router. You need cluster-level privileges, typically clusterAdmin or shardingAdmin.
sh.enableSharding("sales")
sh.shardCollection("sales.orders", { tenant_id: 1, order_date: 1 })
Placeholders: replace sales with your database and sales.orders with your collection. The key document specifies field order and direction; 1 is ascending, hashed indicates a hashed key.
Expected checks after sharding:
sh.status()shows the shard key and chunk distribution across shards.db.orders.getShardDistribution()reports data size and document count per shard.db.orders.find({ tenant_id: "acme" }).explain("executionStats")should show the query targeting the shards that own matchingtenant_idchunks, not every shard.
Risks: sharding an existing collection with large data can trigger initial chunk splits and migrations. Low-cardinality prefix values create indivisible chunks and may produce jumbo chunks that block balancing.
Validation under load
Before committing to a key in production, test insert throughput with a representative workload. Monitor mongos and shard logs for frequent chunk migrations or one shard receiving most inserts. If you see a single shard approaching disk or CPU limits while others are idle, the shard key is likely skewed.
Limitations
- Shard keys cannot be modified document-by-document; changing the key requires resharding (MongoDB 5.0+) or rebuilding the cluster.
- Multi-shard transactions and scatter-gather queries add latency compared to single-shard operations.
- Hashed keys do not support efficient range scans on the hashed field.
Practical check
After sharding, run sh.status() and confirm no shard holds a disproportionate share of chunks. Then run db.orders.getShardDistribution(); if one shard holds more than roughly double the data of another, revisit the shard key or add a more selective prefix field.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.