Introduction Building an index on a large MongoDB collection can block writes for extended periods, especially on MongoDB 4.2 and earlier where foreground builds acquire exclusive locks. Even background builds in newer versions can cause write stalls when the collection has millions of documents.

Symptoms - Write operations timeout with `LockBusy` during index creation - `db.currentOp()` shows long-running `createIndex` operation blocking other ops - Application experiences write latency spikes correlating with index build start time - Index build fails with `Index build aborted due to stepdown` during replica set failover - Disk I/O spikes during index build causing slowdown on all operations

Common Causes - Foreground index build on MongoDB 4.2 or earlier blocking all database writes - Building index on a collection with millions of documents without `background: true` - Insufficient memory for the index build sort phase, causing disk spills - Replica set stepdown interrupting index builds - Building multiple indexes simultaneously competing for I/O

Step-by-Step Fix 1. **Check current index build operations**: ```javascript db.currentOp({ "op": "command", "msg": /^Index Build/ }) // Or for all ops blocking writes db.currentOp({ "waitingForLock": true }) ```

  1. 1.Kill a stuck or problematic index build:
  2. 2.```javascript
  3. 3.var ops = db.currentOp({ "msg": /^Index Build/ });
  4. 4.ops.inprog.forEach(function(op) {
  5. 5.print("Killing op: " + op.opid);
  6. 6.db.killOp(op.opid);
  7. 7.});
  8. 8.`
  9. 9.Build the index in the background (MongoDB 4.2+)":
  10. 10.```javascript
  11. 11.// Background build is default in MongoDB 4.2+
  12. 12.db.collection.createIndex({ status: 1, created_at: -1 })

// For explicit control in older versions: db.collection.createIndex({ status: 1 }, { background: true }) ```

  1. 1.Build indexes on secondaries first (rolling index build)":
  2. 2.```javascript
  3. 3.// Step 1: Stop the balancer (for sharded clusters)
  4. 4.sh.stopBalancer();

// Step 2: Build on each secondary one at a time // Connect to a secondary and build db.collection.createIndex({ field: 1 });

// Step 3: Step down the primary rs.stepDown();

// Step 4: Build on the new primary (was a secondary with the index) // The index build on the new primary will be fast as it already exists ```

  1. 1.Use the inMemory build option for faster creation (MongoDB 5.0+)":
  2. 2.```javascript
  3. 3.// Requires sufficient RAM to hold the index in memory
  4. 4.db.collection.createIndex(
  5. 5.{ user_id: 1, created_at: -1 },
  6. 6.{ buildIndexes: true }
  7. 7.);
  8. 8.`
  9. 9.**Monitor index build progress":
  10. 10.```javascript
  11. 11.// Check index build progress
  12. 12.db.adminCommand({ createIndexes: "collection", indexes: [] });

// Check indexes built so far db.collection.getIndexes();

// Monitor disk I/O during build // mongostat --discover 1 ```

Prevention - Build indexes during maintenance windows or low-traffic periods - Use rolling index builds: build on secondaries first, then step down the primary - Monitor index build progress with `db.currentOp()` before starting - Set appropriate `maxTimeMS` on index creation to avoid indefinite blocking - Use MongoDB 5.0+ where index builds are more efficient - For sharded clusters, stop the balancer before building indexes - Pre-create indexes on new collections before populating with data - Test index builds on production-sized data in staging first