Monotonic Clock and Wall Clock

In computing, clocks are used to measure time, but different types serve different purposes. This article explains the differences between monotonic clocks and wall clocks, with a focus on Go programming.

Monotonic Clock

A monotonic clock is an internal timer in a program used to measure elapsed time. It is not affected by user modifications to the system time, such as manual adjustments or NTP updates. This makes it ideal for measuring durations accurately.

Monotonic clocks ensure that time always moves forward, preventing issues like negative elapsed times due to clock changes.

Wall Clock

A wall clock, also known as the system clock or real-time clock, is the user-visible clock displayed by commands like date. It can be adjusted by users or system administrators and may jump forward or backward due to daylight saving time changes or synchronization.

Wall clocks are suitable for displaying timestamps or scheduling events based on absolute time.

Key Differences

  • Monotonic Clock: Measures relative time (elapsed time). Immune to system time changes. Used for timeouts, profiling, and performance measurements.
  • Wall Clock: Measures absolute time. Affected by system time changes. Used for logging events with timestamps or scheduling.

Using Clocks in Go

Go’s time package provides functions for both types of clocks.

Wall Clock

package main

import (
    "fmt"
    "time"
)

func main() {
    now := time.Now() // Wall clock time
    fmt.Println("Current time:", now)
}

Monotonic Clock

Go automatically uses monotonic clocks for elapsed time measurements.

package main

import (
    "fmt"
    "time"
)

func main() {
    start := time.Now()
    // Simulate work
    time.Sleep(2 * time.Second)
    elapsed := time.Since(start) // Uses monotonic clock internally
    fmt.Println("Elapsed time:", elapsed)
}

time.Since() and time.Until() use monotonic clocks to ensure accurate measurements.

Important Points

  • Accuracy: Monotonic clocks provide precise elapsed time, unaffected by external changes.
  • Use Cases: Use monotonic for benchmarks, timeouts; use wall for user-facing timestamps.
  • Platform Differences: Implementation varies by OS, but Go abstracts this.
  • NTP and Adjustments: Wall clocks can cause issues in long-running programs; monotonic avoids this.
  • Best Practices: For critical timing, prefer monotonic clocks. Always consider time zones for wall clocks.

Conclusion

Understanding monotonic and wall clocks helps write reliable Go programs. Use the appropriate clock for your needs to avoid timing-related bugs.

Resources