When a MongoDB secondary starts falling behind, replication lag is usually the first metric we check.
That makes sense. If a secondary is 10 minutes behind, we know there is a delay. If it is two hours behind, we know the situation needs attention.
But there is another question that is just as important:
How much op-log history is still available for that secondary to catch up?
This is where the op-log window becomes important.
A secondary can have 30 minutes of replication lag and still have plenty of time to recover if the op-log contains several days of history. Another secondary can have the same 30 minutes of lag but only one hour of op-log history available.
The lag is the same. The recovery risk is not.
That is the main idea behind this blog.
What is the MongoDB op-log?
The MongoDB op-log is a special capped collection stored in the local database:
local.op-log.rs
The primary records data-changing operations in the op-log, and secondary members read and apply those operations.
The important thing to remember is that the op-log is not an unlimited history of database changes.
It is a rolling history.
As new operations are added, older operations eventually roll off.
For example, suppose the current op-log contains approximately 72 hours of history.
That means a secondary that falls behind by 10 minutes can normally find the operations it needs and continue catching up.
But if a secondary falls behind far enough that the operations it needs have already rolled off the op-log, normal replication catch-up is no longer possible.
This is where the problem becomes much more serious.
Replication lag and op-log window are not the same thing
This is one of the easiest concepts to overlook.
Replication lag tells us how far behind a secondary is now.
Oplog window tells us how much historical op-log data is currently available.
Consider these two situations:
| Replica Set A | Replica Set B | |
| Replication lag | 15 minutes | 15 minutes |
| Oplog window | 72 hours | 1 hour |
Both secondaries are 15 minutes behind.
But Replica Set A has a much larger recovery margin. Replica Set B is already much closer to the point where the available op-log history could become insufficient.
So when looking at replication health, don’t look at lag in isolation.
Look at lag and op-log window together.
How do I check the op-log window?
One of the simplest commands to start with is:
rs.printReplicationInfo()
A typical output contains information similar to:
configured op-log size: 100000MB
log length start to end: 172800secs
op-log first event time: Mon Sep 21 2026 08:00:00 GMT+0530
op-log last event time: Wed Sep 23 2026 08:00:00 GMT+0530
now : Wed Sep 23 2026 09:00:00 GMT+0530
For a beginner, the important value here is:
log length start to end: 172800secs
Convert that into hours:
172800 / 3600 = 48 hours
So the current op-log window is approximately 48 hours.
The first and last event timestamps also show the period currently covered by the op-log.
One important distinction:
Oplog size and op-log window are not the same thing.
A 100 GB op-log does not automatically mean that you have a fixed number of hours of history.
The number of hours depends on how quickly the workload is generating op-log entries.
Now check replication lag
Once we know the op-log window, the next question is:
Is any secondary actually falling behind?
A simple command to check this is:
rs.printSecondaryReplicationInfo()
For example:
source: secondary01
syncedTo: Wed Sep 23 2026 08:59:50 GMT+0530
0 secs (0 hrs) behind the primary
source: secondary02
syncedTo: Wed Sep 23 2026 08:30:00 GMT+0530
1800 secs (0.5 hrs) behind the primary
Here:
- secondary01 is essentially caught up.
- secondary02 is approximately 30 minutes behind.
That makes secondary02 the member we should investigate.
But 30 minutes of lag by itself doesn’t tell us whether we are close to a serious problem.
We need to compare it with the op-log window.
A simple way to think about recovery headroom
Suppose:
Oplog window = 48 hours
Replication lag = 30 minutes
There is a large difference between the two.
A simple approximation is:
Recovery headroom ≈ Oplog window – Replication lag
So:
48 hours – 0.5 hours = 47.5 hours
Now consider a different situation:
Oplog window = 6 hours
Replication lag = 4 hours
The same calculation gives:
6 hours – 4 hours = 2 hours
That is a much smaller margin.
This isn’t a guaranteed “two hours until failure” calculation. Oplog generation and replication lag can change quickly.
It is simply a useful way to understand how much recovery margin exists at that moment.
Why can the op-log window suddenly shrink?
This is where workload becomes important.
Imagine an op-log with 100 GB of capacity.
If the workload generates:
5 GB/hour
then the same capacity represents roughly:
100 / 5 = 20 hours
of history.
Now suppose a batch job starts generating:
20 GB/hour
The 100 GB capacity now represents only:
100 / 20 = 5 hours
The op-log configuration did not change.
The workload changed.
This is why a replica set can have a comfortable op-log window for months and then suddenly see that window collapse after a workload change.
Common contributors include:
- High insert activity
- Heavy updates
- Large deletes
- Batch jobs
- Data migrations
- Increased application traffic
- Higher transaction activity
So when the op-log window starts shrinking, one of the first questions worth asking is:
Did the workload change recently?
A production-style example
Consider a three-member replica set:
Primary
/ \
/ \
Secondary A Secondary B
In the morning, everything looks healthy:
Oplog window = 72 hours
Secondary B lag = 5 seconds
Later, an application batch job starts.
The workload generates more writes, and Secondary B cannot apply the incoming operations as quickly as before.
Over the next few hours, the metrics look like this:
Replication lag
5 sec
↓
30 sec
↓
5 min
↓
30 min
↓
2 hours
At the same time:
Oplog window
72 hours
↓
60 hours
↓
40 hours
↓
24 hours
↓
12 hours
The important observation isn’t simply that lag reached two hours.
The more important observation is that lag is increasing while the available op-log history is shrinking.
That is an early warning.
The secondary may still be functioning normally, but its recovery margin is disappearing.
If lag is increasing, where should I look?
Before increasing the op-log, find out why the secondary is falling behind.
There are four areas I would check.
1. Storage
If the secondary is struggling with storage latency, it may not be able to apply operations quickly enough.
Look at:
- Disk latency
- IOPS
- Throughput
- Disk queue
- WiredTiger-related metrics
A possible pattern is:
Higher storage latency
↓
Slower op-log application
↓
Replication lag increases
↓
Oplog recovery margin decreases
2. CPU
Check whether the secondary has enough CPU to process the incoming workload.
But avoid the assumption:
“CPU is high, so CPU is the problem.”
Instead ask:
What is consuming the CPU while the secondary is falling behind?
That distinction matters because high CPU can be a symptom of increased workload rather than the underlying cause.
3. Network
The secondary needs to receive op-log operations from the primary.
Check for:
- Network latency
- Throughput limitations
- Packet errors
- Bandwidth constraints
A network problem can prevent the secondary from receiving operations quickly enough.
4. Application workload
Look for recent changes such as:
- New application deployment
- Batch processing
- Bulk updates
- Large deletes
- Data migration
- Increased traffic
Sometimes the replication problem is really a workload problem that is showing up as replication lag.
When does the problem become an initial sync?
Normally, a lagging secondary catches up by reading the missing operations from the op-log.
For example:
Primary op-log:
10:00 → 11:00 → 12:00 → 13:00
Suppose the secondary is currently at 11:00.
It can read the operations after 11:00 and continue catching up.
But the op-log keeps rolling.
If the oldest available operation later becomes 12:00 while the secondary is still at 11:00, the operations between 11:00 and 12:00 are no longer available.
The secondary cannot simply continue from where it stopped.
It may now require an initial sync.
The important point is that initial sync is not where the problem started.
The warning signs appeared earlier:
Replication lag increasing
+
Oplog window shrinking
+
Recovery margin decreasing
Those are the signals a DBA should notice before the secondary becomes too stale.
Why does initial sync make op-log sizing important?
An initial sync is considerably more work than normal replication catch-up.
The secondary needs to synchronize its data while the primary continues processing new writes.
Consider:
Initial sync duration = 30 hours
Oplog window = 12 hours
The available op-log history may not be sufficient to cover all the changes generated while the initial sync is running.
This is why op-log sizing should consider more than normal replication lag.
The environment’s workload, peak op-log generation rate, expected maintenance periods, and recovery requirements all matter.
Should we simply increase the op-log?
Not necessarily.
Suppose the secondary has a storage problem:
Secondary disk latency = 100 ms
If we simply increase the op-log, we have given the secondary more history to work with.
But we haven’t made the secondary apply operations any faster.
If the underlying problem continues, the larger op-log will eventually start shrinking too.
So there are really two separate objectives:
Protect the recovery window
Increase op-log capacity when the existing retention does not provide enough recovery margin.
Fix the bottleneck
Investigate the actual reason the secondary is falling behind—storage, CPU, network, workload, or secondary sizing.
Increasing the op-log can provide more time.
It should not be used as a substitute for fixing the reason replication is falling behind.
What should a DBA monitor?
For a production replica set, I would keep the monitoring focused on a few related signals:
Replication
- Replication lag
- Oplog window
- Replica set member state
Oplog
- Oplog generation rate
- Oplog window trend
Secondary performance
- CPU
- Disk latency
- IOPS
- Throughput
- WiredTiger metrics
Workload
- Inserts
- Updates
- Deletes
- Transactions
- Batch activity
The value isn’t in collecting every possible metric.
It’s in connecting them.
For example:
Oplog generation ↑
+
Disk latency ↑
+
Replication lag ↑
+
Oplog window ↓
Together, those signals tell us much more than looking at replication lag alone.
A practical troubleshooting sequence
When replication lag starts increasing, a simple starting workflow is:
1. Identify the affected secondary
rs.printSecondaryReplicationInfo()
2. Check the available op-log history
rs.printReplicationInfo()
3. Compare lag with the op-log window
Ask:
How much recovery margin do we have?
4. Look at the trend
Is lag increasing?
Is the op-log window decreasing?
5. Check whether op-log generation has increased
Did the application workload change?
6. Check the secondary
Look at CPU, storage, network and WiredTiger activity.
7. Check recent application changes
Look for deployments, batch jobs, migrations or unusual write activity.
8. Review op-log sizing
If the current window does not provide enough recovery margin for the environment, consider whether the op-log needs to be increased.
This keeps the investigation focused on both the symptom and the reason behind it.
Final takeaway
Replication lag is an important metric, but it doesn’t tell the whole story.
A secondary may be behind and still have plenty of time to recover. Another secondary with the same amount of lag may be much closer to losing the op-log history it needs.
So the next time you see replication lag increasing, don’t stop at:
“How far behind is the secondary?”
Also ask:
“How much op-log history do I still have, and how quickly is that window being consumed?”
That small change in how we look at replication can help us identify a problem before a lagging secondary turns into an initial-sync event.