1. Shards, Chunks & mongos
A sharded cluster splits one logical collection's data across multiple shards — each shard is itself a replica set, so sharding and replication compose rather than compete. Three pieces make it work together:
- Shards — each one holds a subset of the collection's documents, as its own replica set.
- Chunks — MongoDB splits the collection's range of shard-key values into chunks, and distributes chunks across shards, automatically rebalancing them as data grows.
mongos— the router applications actually connect to. It knows which shard(s) hold the chunks relevant to a query and routes accordingly, so application code never talks to a shard directly.
sh.enableSharding("shop");
sh.shardCollection("shop.orders", { customerId: 1 });
// { customerId: 1 } is the shard key -- every document's shard is
// determined by the value of this field
3. Hot Shards & Bad Key Choices
The most common sharding mistake is picking a key that's monotonically
increasing — an auto-incrementing counter, or a plain ObjectId used
on its own (which is itself roughly time-ordered).
sh.shardCollection("shop.orders", { _id: 1 });
// _id values are roughly time-ordered -- every NEW order's key value is
// higher than every existing one, so every new order lands on the SAME
// chunk, and therefore the SAME shard, until that chunk splits and moves
Every write briefly piles onto one "hot" shard instead of spreading across the cluster — exactly the imbalance sharding was supposed to eliminate. A common fix is a compound shard key that pairs a naturally distributing field with the field queries actually need:
sh.shardCollection("shop.orders", { customerId: 1, _id: 1 });
// customerId spreads writes across many distinct values;
// _id as the second component keeps each customer's chunk ranges ordered
4. Targeted vs. Scatter-Gather Queries
Once a collection is sharded, the shard key you chose also determines how cheap or expensive a given query is to run.
// TARGETED -- includes the shard key, mongos routes straight to one shard
db.orders.find({ customerId: ObjectId("c1") });
// SCATTER-GATHER -- no shard key in the filter, mongos must ask EVERY
// shard and merge the results, even though only a few documents match
db.orders.find({ status: "shipped" });
A scatter-gather query still returns correct results — sharding never changes correctness — but it loses the scaling benefit sharding was meant to provide, since every shard does work regardless of how few of its documents actually match. This is exactly why "query isolation" is one of the three shard-key properties from Section 2: pick a key your dominant query pattern actually filters on.
5. When to Actually Reach for Sharding
Sharding adds real operational complexity — more processes to run, a shard key you can't easily change, scatter-gather queries to watch for — so it's worth reaching for only once replication alone genuinely can't keep up. Signals that usually indicate it's time:
- The working data set no longer fits comfortably in a single primary's available RAM, causing frequent disk reads and degraded performance.
- Write throughput is approaching what a single primary can sustain, even after indexing and query optimization.
- Total data volume is approaching the practical storage limits of a single node.
A replica set that's simply read-heavy is usually better solved with more
secondaries and secondaryPreferred reads from Week 7 — sharding is the
answer specifically to write throughput or data volume outgrowing a single primary,
not to general traffic growth.
A well-indexed replica set on reasonably provisioned hardware handles a surprisingly large amount of traffic. Treat sharding as a deliberate response to a measured bottleneck, not a default architecture to reach for "to be safe" — the shard key decision is hard to undo, and the added complexity is a real ongoing cost.
6. Hands-on Exercise
Evaluate two shard key candidates for a real workload
No cluster required for this one — the exercise is in reasoning through the tradeoffs, which is where most real shard-key mistakes actually happen.
Requirements:
- Given an
eventscollection logging{ _id, userId, eventType, createdAt }at high write volume, write out why{ createdAt: 1 }alone would create a hot shard. - Propose a compound shard key for
eventsthat spreads writes evenly and keeps the application's dominant query — "all events for one user in a date range" — targeted to a single shard. Justify your choice against all three properties from Section 2. - List two query patterns against your chosen key that would still be scatter-gather, and explain why they can't be targeted.
- Write a short paragraph arguing whether this
eventscollection should actually be sharded yet, or whether a well-indexed replica set would do, using the signals from Section 5.
A common answer for step 2 is { userId: 1, createdAt: 1 } — userId gives even distribution across many users, and having it as the leading key field means a "this user's events" query is targeted. Compare your reasoning against that, and be explicit about why field order in a compound shard key matters for which queries end up targeted.
7. Knowledge Check
Four quick questions. Expand each to check your answer.
Q1
What is the mongos process, and why does application code connect to it instead of to a shard directly?
What is the mongos process, and why does application code connect to it instead of to a shard directly?
mongos is the router that knows which shard (or shards) hold the chunks relevant to a given query, and routes the query accordingly. Applications connect only to mongos, never to individual shards, so the application never needs to know how many shards exist or which one holds which data — that routing logic is entirely mongos's job.
Q2
Why does sharding a collection on { _id: 1 } alone typically create a hot shard?
Why does sharding a collection on { _id: 1 } alone typically create a hot shard?
A default ObjectId is roughly time-ordered, so every newly inserted document's _id is higher than nearly every existing one. That means every new write lands on the same chunk at the high end of the key range — and therefore the same shard — until that chunk splits and migrates, defeating the point of spreading writes across the cluster.
Q3
A query filters on a field that isn't part of the shard key. Is the result still correct? What's the cost?
A query filters on a field that isn't part of the shard key. Is the result still correct? What's the cost?
Yes — sharding never affects correctness, only performance. Without the shard key in the filter, mongos can't determine which shard holds the matching documents, so it sends a scatter-gather query to every shard and merges the results. That costs work on every shard even if only one of them actually holds matching data.
Q4
A replica set is struggling under heavy read traffic, but writes and data volume are both modest. Is sharding the right fix?
A replica set is struggling under heavy read traffic, but writes and data volume are both modest. Is sharding the right fix?
Not necessarily — sharding is the answer specifically to write throughput or total data volume outgrowing what a single primary can handle. Read-heavy traffic with modest writes and data size is usually better addressed with more secondaries and secondaryPreferred reads (Week 7), which is far simpler to operate than an irreversible shard-key decision.