Wall-clock time can move; process clocks drift
coreintermediateWall-clock time is the human-facing notion of "what time is it right now" — and the fact that it "can move" refers to something most application code implicitly assumes cannot happen: a system clock does not only ever advance smoothly forward. NTP (Network Time Protocol) synchronization, which most servers use to keep their clocks accurate, corrects a clock periodically against a reference time source, and that correction can move the clock backward as well as forward if it had drifted ahead — meaning code that reads the wall clock twice in a row and assumes the second reading is always greater than or equal to the first can be wrong. Separately, even between synchronization corrections, every machine's clock runs on its own local oscillator, which is not perfectly accurate — this is clock drift, and it means two machines' clocks, even if synchronized a moment ago, will have diverged by some small amount by the time either is read again, with the exact amount of divergence depending on hardware quality and how recently each was last corrected. Neither of these is a rare hardware fault; both are the normal, expected behavior of real clocks on real machines, in every data center, all the time. Code that treats wall-clock time as instantaneous, monotonically increasing, and identical across machines is making three assumptions that are each false in the general case, and a design that depends on any of them being true needs a different tool for that specific need — which is exactly what the next two concepts in this section provide.
Think of it as
A room full of wall clocks, each slightly cheap and slightly different, all periodically walked past and nudged closer to the "true" time by someone carrying a reference clock — sometimes that nudge sets a clock forward, and sometimes, if it had been running fast, the nudge sets it backward. Between nudges, every clock in the room keeps ticking at its own very slightly wrong rate, so even two clocks nudged to agree exactly a minute ago will not read exactly the same time now. Nobody would build a stopwatch out of "the reading on whichever wall clock happens to be nearest" — not because wall clocks are broken, but because that was never the job a wall clock does well; a stopwatch needs a mechanism that only ever counts forward from a fixed start, which is a fundamentally different kind of device.
What we're doing: Trace a duration measurement across an NTP correction and see it go negative.
- 4
- This step is the normal, periodic behavior of an NTP client keeping the machine's clock accurate — it is not a malfunction, and it happens on essentially every server running standard time synchronization.
- 8
- The measured duration is negative despite real, physical time having genuinely passed between the two reads — the wall clock, not the passage of time itself, moved backward, and code trusting the wall clock as a stopwatch inherits that discontinuity.
Why this works: The bug here is not in the NTP correction, which is doing exactly its job (keeping the clock accurate) — the bug is in using `time.time()` (a wall clock, designed to tell you what time it is) for a job it was never designed for (measuring elapsed duration, which needs a clock that only ever counts forward).
Measuring elapsed duration with the wall clock
Wrong
Better
What you see: A rate limiter or a timeout mechanism that computes "has more than 5 seconds passed" using the wall clock occasionally reports a negative or absurdly large elapsed time right after an NTP correction, causing a request to be incorrectly allowed through a limiter that should have blocked it, or a timeout to fire (or fail to fire) at the wrong moment.
Why: The wall clock and the monotonic clock answer two genuinely different questions — "what time is it" versus "how much time has passed" — and only the second question has an answer that must never go backward; using the wall clock (built for the first question) to answer the second inherits every discontinuity the wall clock is allowed to have.
- T+0: Clock synchronized — matches reference time exactly
- T+30min: Drift accumulates — local oscillator runs slightly fast; clock is now ahead
- T+60min: NTP correction — clock is stepped backward to match reference time
- T+60min+ε: A reading taken just after — can be earlier than a reading taken just before the correction
Two distinct clock behaviors and what each one breaks
Remember: A wall clock can move backward (NTP corrections) and two machines' wall clocks continuously drift apart between corrections (clock drift) — both are the normal, expected behavior of real clocks, not rare faults. Never use the wall clock to measure elapsed duration (use a monotonic clock instead) and never assume two machines' wall-clock timestamps are precise enough for an exact ordering decision, even when both run NTP in the same data center.
See also: dont rely on local timestamps for ordering · utc monotonic clocks and logical ordering · timestamps sequence numbers and version checks

