· 2 min read ·

Why std::chrono::high_resolution_clock Is Rarely the Clock You Want

Source: isocpp

Back in January, Sandor Dargo published a careful breakdown of std::chrono::high_resolution_clock that is worth revisiting. The core finding is simple but easy to overlook: the name does not guarantee what it implies.

What the Standard Actually Says

The C++ standard allows std::chrono::high_resolution_clock to be a typedef for either std::chrono::system_clock or std::chrono::steady_clock. On most major platforms, it is. On Linux with GCC and Clang, it typically aliases system_clock. On MSVC, it aliases steady_clock. The name suggests precision; what you get depends on the implementation.

This matters because the three clocks have meaningfully different properties:

  • system_clock: wall time, can jump forward or backward (NTP adjustments, DST, manual changes)
  • steady_clock: monotonically increasing, never goes backward, not tied to wall time
  • high_resolution_clock: one of the above, platform-defined

The Practical Problem

Suppose you are benchmarking a function:

auto start = std::chrono::high_resolution_clock::now();
do_work();
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

If high_resolution_clock aliases system_clock on your platform, a clock adjustment between those two calls can corrupt the measurement. You get a negative duration, or an absurdly large one. The code looks correct and compiles cleanly. The results are garbage.

steady_clock does not have this problem. It is monotonic by definition, so the difference between two calls will always be non-negative and reflects real elapsed time.

When Each Clock Is Appropriate

For measuring elapsed time, profiling, or any duration-based logic, steady_clock is the correct choice. It does what you want and makes the intent clear in the source.

For recording when something happened, correlating with external systems, or displaying time to a user, system_clock is appropriate. It is the one connected to the actual calendar.

high_resolution_clock has a narrow legitimate use: when you specifically need the finest tick resolution available and have verified what it aliases on your target platform. That is a specialized need, not the general precision tool the name suggests.

The Naming Problem

This is fundamentally a naming issue baked into the standard. “High resolution” describes the tick granularity in the best case, not the monotonicity or stability of the clock. Developers reaching for it because it sounds the most precise are making a reasonable inference that the design invites and the spec does not reliably deliver.

Dargo’s article traces through the standard wording and platform behavior in detail, and it is a good reference to keep around. The short version: when you care about measuring how long something took, write steady_clock. It is a less exciting name, but it is the right one.

Was this interesting?