Rebuild a MongoDB Index Online
Rebuild a fragmented MongoDB index without blocking writes by leveraging rolling index builds on a replica set.
Task
Rebuild a fragmented index safely across replica set members to avoid write downtime.
When to use this
A large index grows fragmented and query latency creeps up, but a full index rebuild would block writes on the primary.
Prerequisites
- A MongoDB replica set
- Rolling upgrade ability across members
- Monitoring for query latency
Steps
1. Rebuild one secondary at a time to avoid impacting the primary.
rs.stepDown();
rs.status().members.map(m => ({ name: m.name, stateStr: m.stateStr }));Expected output: The member is stepping down so another primary serves writes while the index rebuilds.
2. Rebuild the index on each secondary in turn.
mongosh --eval 'db.orders.reIndex({ keyPattern: { createdAt: 1 } })'Expected output: Each secondary rebuilds offline from the primary perspective, keeping writes available.
Troubleshooting
Problem
Primary rebuild blocks writes
Solution
Always rebuild secondaries first and only rebuild the primary during a maintenance window.
Problem
Rebuild fails for lack of disk
Solution
Provision space for the new index before dropping the old one.
Limitations
- Requires a replica set with spare capacity.
- Rolling rebuilds take longer than an offline rebuild.
- Does not address index design issues that cause fragmentation.
What this recipe does
Rebuild a fragmented index safely across replica set members to avoid write downtime.
A large index grows fragmented and query latency creeps up, but a full index rebuild would block writes on the primary.
Prerequisites
- A MongoDB replica set
- Rolling upgrade ability across members
- Monitoring for query latency
Procedure
- Rebuild one secondary at a time to avoid impacting the primary.
rs.stepDown();
rs.status().members.map(m => ({ name: m.name, stateStr: m.stateStr }));
Expected result: The member is stepping down so another primary serves writes while the index rebuilds.
- Rebuild the index on each secondary in turn.
mongosh --eval 'db.orders.reIndex({ keyPattern: { createdAt: 1 } })'
Expected result: Each secondary rebuilds offline from the primary perspective, keeping writes available.
How to confirm it worked
Run the commands above and confirm every expected result in order. If a step does not produce the stated output, use the troubleshooting notes before continuing. A passing run shows each member reports the rebuilt index and query p99 latency returns to baseline without write downtime.
Troubleshooting
Primary rebuild blocks writes — Always rebuild secondaries first and only rebuild the primary during a maintenance window.
Rebuild fails for lack of disk — Provision space for the new index before dropping the old one.
Limitations
- Requires a replica set with spare capacity.
- Rolling rebuilds take longer than an offline rebuild.
- Does not address index design issues that cause fragmentation.