This behavior was observed in 3.4.4 (at least). The reason is that TimerHolder is declared here in applyOps, but applyOps doesn't wait for the batch to finish. This can be solved by moving TimerHolder to this block which does wait for the batch to finish. This would need to be done at each place where applyOps is called.
This makes it difficult to determine whether the node is under heavy replication load and to diagnose issues related to that.