Introduction WiredTiger, MongoDB's default storage engine, uses an in-memory cache to buffer reads and writes. When the cache fills faster than the eviction thread can flush dirty pages to disk, write operations stall waiting for cache space. This "eviction thrashing" causes write latency spikes and throughput drops.

Symptoms - Write latency spikes from milliseconds to seconds during peak load - MongoDB logs show `WT_CACHE: waiting for eviction` messages - `db.serverStatus().wiredTiger.cache` shows `eviction server stuck` or high `tracked dirty bytes` - `current queued evictions` consistently above 100 - CPU usage shows high `iowait` percentage during write stalls

Common Causes - `wiredTigerCacheSizeGB` too small for the write working set - Write pattern generating many small random writes instead of sequential - Insufficient disk IOPS causing eviction threads to fall behind - Large unindexed writes causing full collection scans in cache - Eviction threads configured too conservatively

Step-by-Step Fix 1. **Check WiredTiger cache statistics**: ```javascript // In mongosh var cache = db.serverStatus().wiredTiger.cache; print("Cache used: " + cache["bytes currently in the cache"] / 1024 / 1024 / 1024 + " GB"); print("Cache max: " + cache["maximum bytes configured"] / 1024 / 1024 / 1024 + " GB"); print("Dirty bytes: " + cache["tracked dirty bytes in the cache"] / 1024 / 1024 + " MB"); print("Eviction server stuck: " + cache["eviction server stuck"]); print("Pages queued for eviction: " + cache["pages queued for eviction"]); ```

  1. 1.Increase the WiredTiger cache size:
  2. 2.```yaml
  3. 3.# /etc/mongod.conf
  4. 4.storage:
  5. 5.wiredTiger:
  6. 6.engineConfig:
  7. 7.cacheSizeGB: 8 # Set to ~50% of available RAM
  8. 8.`
  9. 9.```bash
  10. 10.sudo systemctl restart mongod
  11. 11.`
  12. 12.Tune eviction thresholds for write-heavy workloads:
  13. 13.```yaml
  14. 14.storage:
  15. 15.wiredTiger:
  16. 16.engineConfig:
  17. 17.configString: "eviction=(threads_max=8),eviction_dirty_target=5,eviction_dirty_trigger=20"
  18. 18.`
  19. 19.Add missing indexes to reduce cache pressure from unindexed writes:
  20. 20.```javascript
  21. 21.// Find unindexed writes in the profiler
  22. 22.db.system.profile.find({
  23. 23."op": "update",
  24. 24."planSummary": { $ne: "IXSCAN" }
  25. 25.}).sort({ ts: -1 }).limit(10);

// Add the missing index db.collection.createIndex({ status: 1, updated_at: -1 }); ```

  1. 1.Batch writes to reduce individual cache pressure:
  2. 2.```javascript
  3. 3.// Instead of individual inserts
  4. 4.// BAD: for (let i = 0; i < 10000; i++) db.collection.insertOne({...})

// GOOD: bulk write const bulk = db.collection.initializeUnorderedBulkOp(); for (let i = 0; i < 10000; i++) { bulk.insert({ data: item_${i}, created: new Date() }); } bulk.execute(); ```

  1. 1.Monitor disk IOPS to ensure eviction can keep up:
  2. 2.```bash
  3. 3.iostat -x 1 10
  4. 4.# Check %util on the MongoDB data disk - if consistently > 80%, disk is bottleneck
  5. 5.# Check await - if > 10ms, disk latency is too high for eviction
  6. 6.`

Prevention - Set `wiredTigerCacheSizeGB` to approximately 50-60% of available RAM - Monitor `tracked dirty bytes in the cache` and alert when it exceeds 50% of cache size - Use bulk operations instead of individual writes for batch processing - Ensure all write queries are covered by indexes - Use SSDs with sufficient IOPS (minimum 3000 for production workloads) - Consider using `writeConcern: { w: 1, j: false }` for non-critical writes to reduce journal flush overhead - Run `db.serverStatus().wiredTiger.cache` checks every 5 minutes in monitoring