MongoDB sharding is the technique of distributing one logical collection across multiple servers. It is used when one replica set is no longer enough for storage size, write throughput, or read workload.
A sharded cluster has shards that store data, config servers that store cluster metadata, and mongos routers that send application queries to the correct shard. The shard key decides how documents are divided, so choosing it carefully is the most important design decision.
Beginners should first understand the cluster pieces. Experienced developers should focus on shard key cardinality, write distribution, query targeting, chunk movement, and operational safety during resharding or migrations.
For traffic-heavy applications, sharding should be planned alongside indexing, schema design, and deployment topology. The best sharded cluster still performs poorly if queries cannot target shards or if writes concentrate on one range.
A single MongoDB replica set can handle many applications, but eventually it may hit limits. The database may become too large for one server, writes may overload the primary, or common queries may compete for the same resources.
Sharding solves this by spreading documents across multiple replica sets called shards. The application still talks to MongoDB through mongos, so developers usually query the database the same way.
The shard key is one or more indexed fields that MongoDB uses to distribute documents. A good shard key has high cardinality, spreads writes across shards, and appears in common queries so mongos can target specific shards.
A poor shard key can create hot shards. For example, an increasing timestamp may send all new writes to the same range until chunks split and move. A low-cardinality field such as status may create only a few large groups.
When the application sends a query, mongos checks cluster metadata and routes the query. If the query includes the shard key, mongos can often send it only to the shard that owns that range. If the query does not include the shard key, mongos may ask every shard.
This difference is important for performance. A targeted query behaves like a direct lookup. A scatter-gather query can still work, but it consumes resources across the cluster and becomes expensive as the cluster grows.
| Query Type | Example | Result |
|---|---|---|
| Targeted | { tenantId: 42, orderId: 1001 } | Routes to matching shard range |
| Scatter-gather | { status: "pending" } | Checks many or all shards |
| Range query | { tenantId: 42, createdAt: { $gte: date } } | Good when shard key prefix is present |
MongoDB divides sharded data into chunks. As data grows, chunks may split and move between shards so the cluster remains balanced. The balancer handles movement, but administrators still monitor chunk distribution and query performance.
Before enabling sharding, create indexes, understand common query patterns, and test with realistic data volume. Sharding is powerful, but it adds operational complexity that should be justified by real scale needs.
Modern MongoDB supports more flexible operations than early versions, but shard key changes and resharding still require planning. Index compatibility, write traffic, data size, and maintenance windows matter.
In multi-tenant systems, a compound key such as tenantId plus another field can be useful when queries are tenant-scoped. In event-heavy systems, hashed keys may distribute writes well, but range queries become less natural.
Before sharding, confirm that the current replica set has been tuned properly. Review indexes, slow queries, document growth, working set size, disk pressure, and write concern. Sharding adds moving parts, so it should solve a measured bottleneck.
Create a small workload profile: the top read queries, top write paths, expected data growth, and tenant or region requirements. This profile is stronger than choosing a shard key from a guess.
This shell example shows the usual learning flow for enabling sharding.
sh.enableSharding("shop")
use shop
db.orders.createIndex({ tenantId: 1, orderId: 1 })
sh.shardCollection(
"shop.orders",
{ tenantId: 1, orderId: 1 }
)
Including the shard key helps mongos route the query efficiently.
db.orders.find({
tenantId: 42,
orderId: 1001
})
// Better than searching only by status on a huge sharded collection.
db.orders.find({
tenantId: 42,
status: "paid"
})
Experienced MongoDB work includes verifying whether queries target one shard or many.
db.orders.find({ tenantId: 42, orderId: 1001 }).explain("executionStats")
// Review shard information, examined documents, and winning plan.
// If many shards are contacted for a frequent query, revisit indexes and shard key design.
Explore 500+ free tutorials across 20+ languages and frameworks.