How to troubleshoot replication lag in MongoDB clusters

Shiney Jeyachandran
Nov 11, 2026
9
Mins to Read
All
How to troubleshoot replication lag in MongoDB clusters
How to troubleshoot replication lag in MongoDB clusters

Replication lag turns a MongoDB replica set from a safety net into a liability the moment a secondary falls behind the primary, and most teams don't notice until a failover ships stale data. This guide walks through the exact diagnostic sequence DBAs use to find the cause and close the gap in 2026.

TL;DR

  • Run rs.printSecondaryReplicationInfo() first — lag over 10 seconds signals a real problem, not noise.
  • An oplog window under 24 hours means a stalled secondary can't resync without a full reseed.
  • Disk I/O and WiredTiger cache eviction cause more lag than network latency in most 2026 deployments.
  • Unbatched bulk writes spike lag fastest — throttle inserts before blaming the network.
  • Mydbops runs 24/7 monitoring for MongoDB clusters when in-house coverage can't watch the oplog around the clock.

Why this matters

A replica set is only as reliable as its slowest secondary. If that node lags by minutes instead of seconds, a failover during that window loses every write that hadn't replicated yet, and read-preference queries against secondaries return data that's already stale.

MongoDB clusters running high write volume in 2026 — order platforms, gaming leaderboards, tracking feeds — feel this first, because lag compounds under load instead of announcing itself. Mydbops' remote DBA team treats replication lag as a top-tier alert precisely because it hides until it breaks something.

How much replication lag is too much?

Sustained secondary lag behind the primary, from rs.printSecondaryReplicationInfo()

Healthy

Under 2–3 seconds

Normal load

One-off spikes during a deploy or backup self-correct

 
→
Investigate

Sustained above 10 seconds

A real problem, not a monitoring artifact

Confirm with three checks, 30 seconds apart

 
→
Alert now

Over one minute

Risks data loss on failover

Page immediately

 
Alerting rule: page on secondary lag over 10 seconds sustained for 2+ minutes.

Figure 1 · The lag thresholds used throughout this guide.

What you'll need

  • Admin-level access to the replica set (rs.status(), rs.conf())
  • mongostat and mongotop installed on a bastion host or your own workstation
  • Disk and network monitoring on every member (iostat, sar, or your cloud provider's dashboard)
  • The current oplog size and window for each member
  • A maintenance window if you expect to resync a secondary
  • 30-60 minutes for the diagnostic pass, longer if a full resync is needed

The steps

The diagnostic sequence, in order

Each step rules a cause in or out before the next; the dashed card is conditional

Step 1

Confirm the lag is real

rs.printSecondaryReplicationInfo() · 3 checks, 30 s apart

Start here

Step 2

Check the oplog window

db.getReplicationInfo() · oplog size and timeDiff

Sets your runway

Step 3

Isolate the bottleneck node

mongostat qr|qw and dirty · mongotop hot collections

Lag is almost always node-specific

Step 4

Rule out the network

ping · traceroute · mtr for packet loss

Under 5 ms? Move on

Step 5

Find blocking operations

db.currentOp() over 5 s · db.killOp()

Foreground index builds stall the applier

Step 6

Inspect disk and cache

wiredTiger.cache · iostat -x 1

Above 95% cache usage hurts

Step 7

Resync a stalled secondary

Initial sync or filesystem snapshot restore

Only outside the oplog window

 
Order matters: check the oplog window before anything else. It decides whether a lagging secondary can still catch up or needs a full reseed.

Figure 2 · The seven steps covered below.

1. Confirm the lag is real, not a blip

Run rs.printSecondaryReplicationInfo() on the primary. This shows each secondary's syncedTo timestamp against the primary's optime — the delta is your actual lag in seconds.

A lag under 2-3 seconds during normal load is healthy. Anything sustained above 10 seconds is a real problem, not a monitoring artifact. Run the command three times, 30 seconds apart, before you act — a single spike during a deploy or backup window is expected and self-corrects.

Common mistake: treating a one-time spike from a backup job as chronic lag and rebuilding a healthy secondary unnecessarily.

2. Check the oplog window before anything else

The oplog is a capped collection — once it rolls over, a lagging secondary can no longer catch up incrementally and needs a full resync. Run db.getReplicationInfo() and look at the oplog size and timeDiff.

An oplog window under 24 hours is tight for most production workloads; 48-72 hours gives you room to fix a lagging node before it falls out of range entirely. If your window is under 12 hours and lag is already at 5+ minutes, resize the oplog now, before troubleshooting anything else.

Expected outcome: you know exactly how much runway you have before a lagging secondary requires a full reseed instead of a catch-up.

How much oplog runway do you have?

Oplog window from db.getReplicationInfo() timeDiff, on a 0–72 hour scale

Under 12 h
 
Resize now
Under 24 h
 
Tight
48 h
 
Room to fix
72 h
 
Room to fix
 
0 h24 h48 h72 h
 
Under 12 hours with lag already at 5+ minutes: resize the oplog before troubleshooting anything else.

Figure 3 · Once the oplog rolls past a secondary, it can only recover with a full resync.

3. Isolate the bottleneck node with mongostat and mongotop

Run mongostat --host <replicaSetName> across the whole set for 60 seconds. Watch the qr|qw (queue) and dirty (WiredTiger dirty cache percentage) columns on the lagging secondary specifically.

High queue depth on one node and not others points to that node's hardware, not the cluster's write volume. mongotop then tells you which collections are eating read/write time on that node — often a single hot collection with poor indexing.

Common mistake: running mongostat only on the primary and assuming uniform load across secondaries — lag is almost always node-specific.

4. Rule out network latency between replica set members

Ping and traceroute between the lagging secondary and the primary. Cross-region replica sets — a common setup for logistics and e-commerce platforms running 24/7 across time zones — routinely see 40-150ms round trips that compound under high write throughput.

If latency is under 5ms and lag persists, the network isn't your cause — move to disk and cache. If latency is high and variable, check for packet loss with mtr before assuming bandwidth is the issue.

Expected outcome: a clear yes/no on whether network is a contributing factor, so you stop chasing the wrong fix.

5. Check for long-running operations blocking replication

Run db.currentOp({"secs_running": {"$gt": 5}}) on the lagging secondary. A long-running query holding a lock, or an index build running in the foreground, will stall the oplog applier thread behind it.

Kill any non-critical operation over 30 seconds with db.killOp() after confirming it's safe to terminate. Index builds should always run with background: true or, on MongoDB 4.4+, as the default non-blocking build — check your build flags if this keeps recurring.

6. Inspect disk I/O and WiredTiger cache pressure

Check db.serverStatus().wiredTiger.cache for bytes currently in the cache versus the configured cache size (default: 50% of RAM minus 1GB). Sustained eviction pressure above 95% cache usage forces synchronous disk reads that slow the oplog applier directly.

Cross-reference with iostat -x 1 for disk queue depth and %util. A secondary on spinning disk or a shared, noisy-neighbor cloud volume will lag under the exact write load a dedicated NVMe primary handles fine.

Common mistake: assuming all replica set members are provisioned identically — mixed instance types across a set are a frequent, invisible cause of chronic lag.

Four bottlenecks, four signals

What to look for on the lagging secondary in steps 4 to 6 and the troubleshooting notes

Network latency

SignalUnder 5 ms and lag persists: not the network
Checkping · traceroute · mtr
NextHigh and variable? Look for packet loss first

Blocking operations

SignalOperations running longer than 5 s on the secondary
Checkdb.currentOp() · db.killOp()
NextKill non-critical operations over 30 s

Disk and cache pressure

Most common
SignalCache usage above 95%, high disk queue depth
CheckwiredTiger.cache · iostat -x 1
NextMatch secondary hardware to the primary
 

Unbatched bulk writes

SignalLag spikes only during nightly batch jobs
Checkmongostat queue columns during the job
NextBatch 1,000–5,000 documents with a short sleep
In most 2026 deployments: disk I/O and WiredTiger cache eviction cause more lag than network latency.

Figure 4 · Rule each suspect in or out before reaching for a resync.

7. Resync or rebuild a stalled secondary

If the secondary is in RECOVERING state and outside the oplog window, stop the mongod process, wipe the data directory, and let initial sync rebuild from the primary — or restore from a recent filesystem snapshot to skip the full sync entirely.

A full initial sync on a multi-hundred-GB dataset can take hours; snapshot-based resync typically finishes in under 30 minutes. Schedule this during low-traffic windows and monitor rs.status() throughout — a resync that stalls partway through usually means the same disk or network issue that caused the original lag.

Troubleshooting

  • Secondary stuck in RECOVERING state. The node fell outside the oplog window mid-sync. Check rs.status() for the exact state; if syncSourceHost shows no progress for 10+ minutes, kill the sync and restart with a fresh snapshot restore instead of waiting.
  • Oplog window shrinking faster than expected. Write volume increased without a matching oplog resize. Recalculate oplog size at roughly 1 hour of peak writes per GB of oplogSizeMB, and resize with replSetResizeOplog on MongoDB 4.4+ without a restart.
  • Lag spikes only during nightly batch jobs. Bulk imports or ETL writes running without batching overwhelm the applier thread. Break large inserts into batches of 1,000-5,000 documents with a short sleep between batches — this alone often cuts peak lag by half.
  • Lag persists after a full resync. The underlying cause — usually disk I/O or an oversized working set relative to RAM — wasn't fixed, just reset. Re-run steps 3 and 6 immediately after resync completes, not a week later.
  • One region in a multi-region cluster always lags. Cross-region write latency is structural, not a bug. Set that region's member to priority: 0 and hidden: true if it's for read-only analytics, so it never becomes a failover candidate while catching up on its own schedule.

Tools and resources

  • rs.status() and rs.printSecondaryReplicationInfo() — built-in replication health commands
  • mongostat / mongotop — real-time throughput and hot-collection visibility
  • db.serverStatus().wiredTiger.cache — cache pressure diagnostics
  • MongoDB Compass — visual query and index inspection for the hot collections mongotop flags
  • Cloud-native monitoring (CloudWatch, Atlas metrics, or your provider's disk/network dashboards)
  • Platforms with continuous write pressure — SaaS startups running MongoDB at scale tend to hit oplog-window issues earliest because usage grows faster than infrastructure planning

What to do next

Once lag is under control, put alerting on it so this doesn't repeat: page on secondary lag over 10 seconds sustained for 2+ minutes, and alert on oplog window dropping under 24 hours. Document the oplog resize math for your dataset so the next resync doesn't start from zero.

FAQ

What causes replication lag in MongoDB?

Replication lag in MongoDB usually comes from disk I/O bottlenecks, WiredTiger cache eviction pressure, network latency between replica set members, or long-running operations blocking the oplog applier thread. Bulk writes without batching are the most common trigger in 2026 production clusters.

How much replication lag is acceptable in MongoDB?

Under 2-3 seconds during normal load is healthy; sustained lag above 10 seconds needs investigation. Anything over a minute risks data loss on failover and should trigger an alert immediately.

How do I check replication lag in MongoDB?

Run rs.printSecondaryReplicationInfo() on the primary to see each secondary's synced timestamp against the primary's optime. The delta between them is your lag in seconds, and it's the fastest built-in check available.

What happens if a MongoDB secondary falls outside the oplog window?

The secondary can no longer catch up incrementally and enters RECOVERING state, requiring a full initial sync or a snapshot-based restore. This is why monitoring the oplog window matters as much as monitoring the lag itself.

Does resizing the oplog fix replication lag?

Resizing the oplog buys more time before a lagging secondary falls out of range, but it doesn't fix the root cause. Disk I/O, cache pressure, or network latency still need to be addressed separately.

Is replication lag worse on MongoDB Atlas or self-managed clusters?

Neither platform is immune — lag depends on instance sizing, disk type, and write volume more than the hosting model. Atlas gives you built-in metrics for cache and disk pressure that self-managed clusters have to instrument manually.

Can I fix replication lag without downtime?

Yes, in most cases. Oplog resizing on MongoDB 4.4+ requires no restart, and killing a blocking operation or throttling bulk writes takes effect immediately. A full resync of a stalled secondary is the one step that typically needs a maintenance window.

How often should MongoDB replication lag be monitored?

Continuously, with alerting rather than manual checks. Clusters under steady write load in 2026 can go from healthy to a RECOVERING secondary within an hour if lag isn't caught early.

One last thing

The fix teams skip most often isn't a MongoDB setting at all — it's provisioning secondaries on identical hardware to the primary. A lagging node on a cheaper instance type or shared disk tier will keep lagging no matter how many times you resync it, because the bottleneck was never in MongoDB's configuration.

Related guides

Conclusion

Replication lag in MongoDB is rarely a mystery once you work through it in order. Confirm the lag is sustained, check how much oplog runway you have, then isolate the slow node and test each suspect in turn: network latency, blocking operations, disk and cache pressure, and unbatched bulk writes. Resync only when a secondary has genuinely fallen out of the oplog window, and fix the underlying cause first so the same node does not fall behind again. Pair that sequence with continuous alerting on both lag and oplog window size, keep secondaries on the same hardware class as the primary, and replication lag stays an early warning instead of a failover surprise.

No items found.

About the Author

Senior Digital Marketing Specialist at Mydbops. She turns database engineering work into blogs, case studies and webinars, and hosts the MyWebinar series.

Topic covered

Subscribe Now!

Subscribe here to get exclusive updates on upcoming webinars, meetups, and to receive instant updates on new database technologies.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.