MongoDB Sharding
Sharding is MongoDB's method for distributing data across multiple servers to handle extremely large datasets and high-throughput operations. When a single server can no longer store all the data or handle all the incoming requests efficiently, sharding splits the data into smaller pieces called shards and distributes them across multiple machines.
Think of a library with millions of books. Instead of cramming all books onto one floor, the library spreads them across multiple floors — fiction on one floor, science on another, history on a third. Any query goes to the right floor directly. Sharding works the same way for database data.
The Problem Sharding Solves
A database can scale in two ways:
- Vertical Scaling (Scale Up) — Add more RAM, CPU, or storage to a single server. This has a hardware limit and becomes very expensive at high scale.
- Horizontal Scaling (Scale Out) — Add more servers and distribute data across them. Sharding enables horizontal scaling in MongoDB.
Components of a Sharded Cluster
1. Shards
Each shard is a MongoDB Replica Set that holds a portion of the total data. In a cluster with 3 shards, each shard holds roughly one-third of all data.
2. Mongos (Query Router)
The mongos process acts as a router. Applications always connect to mongos, never directly to individual shards. When a query arrives, mongos determines which shard holds the relevant data and routes the request there.
3. Config Servers
Config servers store metadata about the cluster — which shard holds which data. They are deployed as a Replica Set (usually 3 members) and must remain available for the cluster to function. Without config server data, mongos does not know where to route queries.
Sharded Cluster Architecture
Application
|
[mongos] — Query Router
|
[Config Servers] — Cluster metadata
|
___________________________
| | |
[Shard 1] [Shard 2] [Shard 3]
(Replica (Replica (Replica
Set) Set) Set)
Shard Key
The shard key is the most critical decision in sharding. It is a field (or set of fields) that MongoDB uses to determine how to distribute documents across shards. Every document in a sharded collection must have the shard key field.
MongoDB divides shard key values into ranges or hashed buckets and assigns those to specific shards.
Sharding Strategies
Ranged Sharding
Documents are grouped into continuous ranges of shard key values. Each shard receives a range.
Example: Sharding an orders collection by orderDate:
- Shard 1: January 2024 – April 2024
- Shard 2: May 2024 – August 2024
- Shard 3: September 2024 – December 2024
Ranged sharding works well when queries frequently target a specific date range. However, it can lead to uneven data distribution if most writes land in one range (like the current date).
Hashed Sharding
A hash function is applied to the shard key value, and documents are distributed based on the hash result. This spreads documents evenly across shards regardless of the actual key values.
sh.shardCollection("shopDB.orders", { customerId: "hashed" })
Hashed sharding prevents hotspots — situations where one shard receives far more writes than others — making it ideal for write-heavy workloads.
Zoned Sharding (Zone-Based Sharding)
Zones allow specific ranges of shard key values to be pinned to specific shards. This is useful for data locality — keeping user data from a particular country on servers physically located in that country for compliance or latency reasons.
// Assign a tag to shard 1
sh.addShardTag("shard1", "INDIA")
// Assign a key range to that tag
sh.addTagRange(
"shopDB.users",
{ country: "India", _id: MinKey },
{ country: "India", _id: MaxKey },
"INDIA"
)
Setting Up Sharding (Conceptual Steps)
Step 1: Deploy Config Servers
mongod --configsvr --replSet configRS --port 27019 --dbpath /data/configdbInitialize the config server replica set:
rs.initiate({ _id: "configRS", configsvr: true, members: [{ _id: 0, host: "localhost:27019" }] })Step 2: Deploy Shard Replica Sets
mongod --shardsvr --replSet shard1RS --port 27017 --dbpath /data/shard1
mongod --shardsvr --replSet shard2RS --port 27018 --dbpath /data/shard2Step 3: Start Mongos and Connect to Config Servers
mongos --configdb configRS/localhost:27019 --port 27020Step 4: Add Shards to the Cluster
mongosh --port 27020
sh.addShard("shard1RS/localhost:27017")
sh.addShard("shard2RS/localhost:27018")Step 5: Enable Sharding for a Database
sh.enableSharding("shopDB")Step 6: Shard a Collection
sh.shardCollection("shopDB.orders", { customerId: 1 })MongoDB now distributes documents in the orders collection across shards based on the customerId field.
Chunks
MongoDB divides shard key value ranges into units called chunks. Each chunk has a minimum and maximum key range and belongs to one shard. As data grows, large chunks are automatically split into smaller ones. The cluster also balances chunks across shards automatically — if one shard has significantly more chunks than others, the balancer migrates some chunks to underloaded shards.
Choosing a Good Shard Key
The shard key choice directly impacts cluster performance. A poor shard key causes hotspots, uneven distribution, and slow queries.
| Property | Why It Matters |
|---|---|
| High Cardinality | Many unique values allow even distribution across chunks |
| Low Frequency | No single value should appear in a huge number of documents |
| Non-Monotonic | Avoid keys like timestamps that always increase — they cause all new writes to go to one shard |
| Aligns with Queries | Queries that include the shard key target a specific shard instead of querying all shards |
Good Shard Key Examples
userId— High cardinality, evenly distributed users{ userId: "hashed" }— Hash for even distribution{ country, userId }— Compound key for zone-based locality
Poor Shard Key Examples
status— Only a few possible values (active, inactive) leads to huge chunkscreatedAt— Always-increasing value causes write hotspot on the latest shard_id(as ObjectId with ranged sharding) — ObjectIds are monotonically increasing, causing hotspots
Monitoring the Cluster
// Check sharding status
sh.status()
// Check chunk distribution
db.adminCommand({ listShards: 1 })
// Check balancer status
sh.getBalancerState()
Sharding vs Replication
| Feature | Replication | Sharding |
|---|---|---|
| Purpose | High availability, data redundancy | Horizontal scaling, data distribution |
| How it works | All nodes hold all data | Each shard holds a portion of data |
| Handles | Server failures | Data volume and throughput limits |
| Together | Each shard in a cluster is a Replica Set | Sharding and replication work together |
Summary
Sharding in MongoDB distributes data horizontally across multiple servers when a single machine can no longer handle the data volume or query throughput. A sharded cluster consists of shards (Replica Sets that hold data), a mongos router (directs queries to the right shard), and config servers (store cluster metadata). The shard key determines how documents are distributed. Ranged sharding groups nearby values together, while hashed sharding spreads data evenly. Choosing a shard key with high cardinality, low frequency, and non-monotonic growth prevents hotspots and ensures balanced distribution across the cluster.
