Use Python monotonic_ns for Timeouts That Survive Wall Clock Changes
Use Python monotonic_ns to enforce a total timeout budget. Reproduce wall clock adjustments and understand how retries and system suspend affect deadline calculations.
If requests time out too soon or wait too long after a system clock change, check whether your Python service uses time.time() for timeout calculations. To limit how much time an operation spends running, calculate one deadline at the start with time.monotonic_ns() and recompute the remaining time at each step. The example checks whether a request keeps the same time budget when the wall clock moves forward or backward.
Two clocks side by side, one showing a time adjustment and the other advancing steadily
Why the wall clock changes the remaining time
time.time() returns seconds corresponding to calendar time. When the operating system adjusts its clock, the difference between successive calls can reflect both the actual wait and the adjustment. With a five-second timeout, for example, shifting the wall clock 30 seconds backward after two seconds of elapsed time produces a remaining time of 33 seconds. Moving it 30 seconds forward makes the deadline appear to have expired.
time.monotonic_ns() returns an integer count of nanoseconds from a clock that cannot go backward. Its reference point is undefined, so use the difference between readings from the same clock. Use wall time to record dates and expiration timestamps, and a monotonic clock to calculate the remaining time for work in progress. Python time documentation
Calculate the overall deadline once
Set deadline = monotonic_ns() + budget_ns. Before each attempt, recompute remaining_ns(deadline) and skip the attempt if it is zero. For an API that accepts a timeout in seconds, divide the positive remainder by 1_000_000_000. If you wait between retries, keep the wait within the remaining budget and check it again afterward. Giving every attempt the full timeout can let the operation exceed its intended total limit.
Save the code as monotonic_deadline.py and run python3 monotonic_deadline.py. It simulates adjustments with a test clock.
Verify forward and backward adjustments
The example ran on Linux with Python 3.12.14 on November 14, 2026. Both 30-second adjustments left three seconds on the monotonic clock. The test also checked that the remainder becomes zero after additional elapsed time and that a deadline set to the current value from the actual monotonic_ns() clock returns zero.
Keep deadlines within their clock and account for suspend
Use a monotonic deadline with the same clock that produced it. When sending timing information to another host, use a protocol-defined remaining duration or absolute expiration timestamp. When the receiver assigns a new time budget, decide how the protocol accounts for time in transit and differences between host clocks.
On Linux, CLOCK_MONOTONIC is unaffected by discontinuous wall clock changes, but it can be affected by gradual clock adjustments and excludes time spent suspended. Linux tasks that need to count suspend time can use CLOCK_BOOTTIME. Check the clock used by the current Python process with time.get_clock_info("monotonic"). This example simulates the effects of clock adjustments. System suspend and timeout behavior in specific network APIs were outside the test scope. Linux clock_gettime(2) · Python time documentation