Sharded MongoDB explain plans
By Marios Pavlidis · Updated October 2026 · Applies to MongoDB 5.0–8.0 sharded clusters
When you run explain() against a sharded collection, the output structure is different from a standalone or replica set plan. The router (mongos) adds an outer wrapper that describes how it distributed the query across shards and how it merged the results.
Analyzer limitation: The mongodbplan.com analyzer detects sharded explain output and shows the raw JSON rather than a normalized plan tree. Full per-shard plan normalization is not implemented. This guide explains how to read the sharded output manually.
Top-level shape of a sharded explain
A sharded explain adds a queryPlanner.winningPlan at the router level, and each shard's plan is nested inside shards:
{
"queryPlanner": {
"winningPlan": {
"stage": "SHARD_MERGE", // or SINGLE_SHARD
"shards": [
{
"shardName": "shard0",
"winningPlan": {
// per-shard plan — same structure as a non-sharded explain
"stage": "FETCH",
"inputStage": { "stage": "IXSCAN", ... }
}
},
{
"shardName": "shard1",
"winningPlan": { ... }
}
]
}
},
"executionStats": {
"nReturned": 284,
"executionTimeMillis": 14,
"totalKeysExamined": 284,
"totalDocsExamined": 284,
"executionStages": {
"stage": "SHARD_MERGE",
"shards": [
{
"shardName": "shard0",
"executionStages": { ... }, // per-shard execution stats
"executionStats": { ... }
}
]
}
}
}SHARD_MERGE vs SINGLE_SHARD
SINGLE_SHARD
The router determined that only one shard holds the relevant data — typically because the query includes an equality condition on the shard key. The query is forwarded to that shard only and the result is returned directly without merging. This is the most efficient sharded query shape.
SHARD_MERGE
The router broadcast the query to multiple shards and merged results. This is normal for queries that don't include the shard key or that span multiple chunk ranges. The mergeType field indicates where the merge happened.
The mergeType field
Inside queryPlanner.winningPlan, mergeType shows where the router merged per-shard results:
| mergeType | Meaning |
|---|---|
| router | Shards streamed results to the router (mongos); the router sorted/limited in memory. Common for sorted queries. |
| primaryShard | Results were merged on the primary shard. Common for aggregation pipelines with stages that require a single node (e.g. $group without allowDiskUse). |
| anyShard | Results were merged on an arbitrary shard. Similar to primaryShard but without pinning to the primary. |
Reading per-shard execution stats
The top-level executionStats shows aggregate totals across all shards. For query investigation you usually want to look at each shard individually inside executionStages.shards[]:
- Compare
nReturnedacross shards — an imbalance indicates data is not evenly distributed for this query's predicate (chunk hotspot or poor shard key choice for this access pattern). - Check
executionTimeMillisper shard — one slow shard becomes the tail latency for the whole query. - Look at the winning plan on each shard. In a healthy cluster they should be the same. Different plans across shards can indicate index presence or statistics divergence.
Analyzer support
When you paste a sharded explain into the analyzer, it detects the sharded shape and displays the raw JSON with a note that full normalization is limited. It will not produce per-shard plan trees or per-shard findings.
To analyze a sharded query plan today: extract the winningPlan for a single shard from inside executionStages.shards[n] and paste it as a standalone plan. This gives you the full analyzer output for that shard's execution, without the sharded wrapper.