Scaling MongoDB: Replica Sets, Sharding, Shard Keys, Balancing, and Resharding
MongoDB scaling has two separate dimensions: replication for availability/read distribution and sharding for horizontal data and write distribution. Treating them as the same thing leads to confusing capacity plans.
Start with query/index optimization and a correctly sized replica set. Move to sharding when one replica set has a demonstrated storage, write-throughput, or workload-isolation limit.
This article focuses on MongoDB's scaling mechanics. The separate MongoDB architecture article explains the internal components and request path, while the general MongoDB article covers document modeling and everyday development.
Scale up before you scale out
Before adding shards, inspect whether the existing deployment is actually constrained.
Look at:
- slow queries and execution plans
- missing indexes
- working-set memory pressure
- storage latency
- CPU
- connection count
- document growth
- write concern latency
- replication lag
Sharding will not repair a collection whose hot queries are missing the right indexes.
Vertical scaling and query improvements are operationally simpler while they still provide enough headroom.
Replica sets provide availability first
A MongoDB replica set contains one primary and one or more secondary members.
application writes
|
v
primary
/ \
secondary secondary
Writes normally go to the primary. Secondaries replicate the primary's oplog asynchronously.
Replica sets provide:
- redundancy
- automatic primary election
- failover
- backup/read-isolation options
- optional secondary reads
Adding secondaries does not horizontally distribute the primary write workload.
Secondary reads can be stale
MongoDB clients read from the primary by default. Read preference can route eligible operations to secondaries, but secondaries replicate asynchronously.
That means a secondary read can return an older state than the primary.
Use secondary reads for workloads where staleness is acceptable, such as some reporting or analytics queries. Keep read-after-write, authorization-sensitive, or otherwise freshness-critical reads on an appropriate consistency path.
MongoDB also exposes read concern and write concern controls. Use them deliberately rather than assuming every read from every node has identical guarantees.
When sharding becomes justified
Sharding distributes a collection across several shards.
MongoDB's current documentation highlights three primary scaling benefits:
- distribute read/write work
- increase storage capacity
- preserve partial availability when some shard replica sets are unavailable
A simplified topology is:
clients
|
mongos routers
|
+--> shard A replica set
+--> shard B replica set
+--> shard C replica set
|
config server replica set
Each shard is normally a replica set, so sharding and replication work together.
mongos routes operations
Applications connect to mongos, not directly to one shard.
The router uses cluster metadata to determine which shard or shards may contain the requested documents.
A query that contains the shard key—or the useful prefix of a compound shard key—can often be targeted to a small number of shards.
A query without enough shard-key information may become a broadcast/scatter-gather operation across every shard.
That routing difference is one of the biggest reasons shard-key design matters.
The shard key must distribute both data and traffic
A good shard key needs:
- enough cardinality
- even-ish distribution
- query locality
- resistance to hotspots
- a path for future zoning/placement if needed
Suppose a collection is sharded only by tenant_id. That can be excellent for tenant-local queries, but one enormous tenant can still make one shard much hotter than others.
Measure:
- bytes per shard-key range/value
- reads per key/range
- writes per key/range
- largest tenants/users/entities
- growth rate
Even row distribution is not enough if traffic is heavily skewed.
Range vs hashed sharding
Range sharding
Documents are distributed by contiguous shard-key ranges.
This preserves locality for range queries, but monotonically increasing keys can concentrate new writes on one edge of the keyspace.
Good fit when ordered ranges are important and write distribution remains healthy.
Hashed sharding
MongoDB hashes the shard-key value before distribution.
This often spreads inserts more evenly but destroys natural range locality on that field.
Good fit when even write/data distribution matters more than adjacent-key range scans.
Choose from real query and write patterns—not a generic recommendation that “hashed is scalable.”
Compound shard keys can balance locality and distribution
A compound shard key can include several fields.
For example:
{ tenant_id: 1, created_at: 1 }
or another combination designed for your access pattern.
Field order matters. Queries containing the prefix can be routed more efficiently, while queries that omit it may still scatter.
Also consider future MongoDB zones before locking in a key because zone ranges are based on fields contained in the shard key.
Hot keys remain hot after sharding
Sharding distributes different key ranges, but one extremely popular document still has one owning shard.
Examples:
- one viral post counter
- one global config document
- one giant tenant
- one queue/status bucket
If one object requires all writes to serialize through one document/range, adding shards elsewhere cannot make that object horizontally writable.
Potential redesigns include:
- bucketed counters
- append-and-aggregate
- sub-partitioning large tenants
- dedicated placement for exceptional tenants
Scale requires distributable work.
The balancer moves ranges between shards
MongoDB's balancer monitors collection distribution and migrates ranges/chunks when needed.
This helps the cluster adapt as:
- shards are added
- data grows unevenly
- zones require placement changes
- collections become imbalanced
But balancing is real data movement. It consumes disk, CPU, and network resources and can affect workload performance.
Do not assume adding a new empty shard instantly gives the whole cluster balanced capacity. Data must move.
MongoDB 8.x has faster redistribution options
Current MongoDB documentation recommends newer sharding/resharding workflows for supported MongoDB 8.x deployments when immediate redistribution is required. For example, shardAndDistributeCollection can combine initial sharding with resharding to distribute data instead of waiting only for normal balancer migration.
This is version-sensitive operational behavior. Verify the exact MongoDB version and deployment requirements before using it.
The broader lesson is stable: resharding and migration are capacity-consuming operations that need planning.
Resharding is your escape hatch from a bad key
Modern MongoDB can reshard a collection to a new shard key.
That is valuable because application growth can reveal problems that were invisible at launch:
- unexpected tenant skew
- a key that creates hot ranges
- new query patterns
- future geographic placement requirements
But resharding is not free. It moves/rebuilds substantial data and consumes cluster resources.
Choose the initial shard key carefully and still document how you would change it later.
Zones provide data placement control
MongoDB zones associate shard-key ranges with particular shards.
They can support requirements such as:
- keep specific customer data on dedicated hardware
- keep a region's data on region-local shards
- isolate premium/high-throughput tenants
- use shards with different hardware characteristics
Zones depend on the shard-key structure. If geography may matter later, include that possibility in shard-key planning from the beginning.
Scatter-gather can become the hidden scaling tax
A sharded cluster can have plenty of total CPU and still perform poorly if common queries broadcast to all shards.
Examples include searches/filtering that do not include useful shard-key information.
Every broadcast query creates work on several shards plus merge work at the router.
Mitigations include:
- redesigning the shard key around hot access patterns
- adding the right indexes on each shard
- moving global search/reporting to a dedicated search/analytics system
- precomputing global views
A sharded OLTP cluster should not be the universal engine for every global query simply because all data lives there.
Indexes still exist independently on every shard
Sharding narrows where data lives; it does not eliminate the need for indexes.
A targeted query can still be slow if the owning shard scans a large amount of data.
Review:
- index selectivity
- index size
- compound index field order
- covered queries
- per-shard working set
A good shard key plus bad indexes is still a slow system.
Write concern changes failure and latency behavior
MongoDB write concern determines the acknowledgement level requested for writes.
Stronger acknowledgement can improve durability guarantees but requires more replication coordination.
The right setting depends on the workload's acceptable data-loss and latency trade-off.
Do not weaken write concern simply to make a benchmark look faster without documenting what failures can lose acknowledged data.
Read preference is not a universal read-scaling switch
MongoDB supports modes such as primary, secondary, primaryPreferred, secondaryPreferred, and nearest.
Sending read traffic to secondaries can reduce primary read work, but:
- data may be stale
- transactions with reads have routing restrictions
- secondaries also need capacity for replication
- analytical queries can delay replication or compete for cache/storage
Use secondary reads for workloads whose consistency and resource behavior you understand.
Partial availability is possible in a sharded cluster
If one shard becomes fully unavailable, data owned by that shard is unavailable, while operations targeting healthy shards can potentially continue.
That can improve fault isolation—but only if your application does not introduce a global dependency on the missing shard for every request.
Design user-facing failure behavior around ownership boundaries.
Capacity planning is shard-aware
Do not monitor only cluster-wide averages.
Track per shard:
- data size
- operation rate
- CPU
- memory/cache pressure
- storage latency
- connection count
- replication lag
- chunk/range migration
- top shard-key values
The cluster's practical limit is often the hottest shard, not the average shard.
A sensible MongoDB scaling sequence
For many deployments:
- Fix slow queries and indexes.
- Bound connection pools and concurrency.
- Scale replica-set nodes vertically while simple.
- Add replicas for HA and carefully chosen read workloads.
- Separate heavy analytics/search where appropriate.
- Measure whether one replica set is truly constrained by data/write load.
- Choose a shard key from access patterns and traffic distribution.
- Shard only the collections that need it.
- Monitor hotspots and balancer behavior.
- Plan resharding before skew becomes an incident.
MongoDB scales well when the shard key makes normal requests targeted and normal writes distributable. Sharding is not the beginning of that design—it is the final expression of a data model that already understands ownership and access patterns.
Official references
BUILDING A SAAS PRODUCT?
Explore Lofingo’s end-to-end SaaS platforms, multi-tenant cloud architecture, and high-concurrency backend engineering.
EXPLORE SAAS SERVICES →