Clocks and time in Python

time.time for dates, time.monotonic for timeouts, perf_counter for benchmarks, and a stoppable wait in place of sleep. Every call described, and every class that reads a clock tested on a clock the test moves by hand.

What is the difference between time.time and time.monotonic?

time.time reads the system clock and returns seconds since 1 January 1970 UTC, so it is a date that another machine can read. The system clock can be set, and the documentation warns that time.time can return a lower value than a previous call if the clock was set back in between. time.monotonic cannot go backwards and is not affected by system clock updates, but its starting point is undefined, so only the difference between two readings means anything. Use time.time for when something happened and time.monotonic for how long it took.

Should a timeout use time.time or time.monotonic?

time.monotonic. A timeout is a duration measured inside one process, and a duration computed from two time.time readings is wrong whenever the system clock is set between them; it can even come out negative. The asyncio event loop keeps its own time on a monotonic clock for the same reason.

Is time.perf_counter the same as time.monotonic?

On CPython from 3.13, yes: the documentation says perf_counter uses the same clock as monotonic, and calls that a CPython implementation detail. The language promises only that perf_counter has the highest available resolution for measuring a short duration. Use perf_counter when the job is timing code, so the reader knows the job, and monotonic for timeouts and deadlines.

Why not use time.sleep in a background thread?

Because nothing can wake it. A thread that sleeps for thirty seconds and then checks a stop flag takes up to thirty seconds to notice a shutdown. Wait on a threading.Event with a timeout instead: event.wait(interval) waits as long as a sleep would, and returns at once when another thread calls event.set(). Inside a coroutine, time.sleep is wrong for a different reason: it stops the event loop’s thread, and every task waits. Use await asyncio.sleep there.

How do I test code that reads the clock without making the tests slow?

Pass the clock in. The class takes clock: Callable[[], float] with time.monotonic as the default, and the test passes an object whose call returns a number the test sets and whose advance method moves it. The test then moves time by exactly the amount it needs, the result is the same on every run, and no test sleeps.