Clock Drift
My Arch desktop had drifted a minute ahead of two clocks I never question: my radio-controlled Casio GW-B5600 and my phone. The watch receives a longwave time signal to set itself. The phone gets network time. They agreed with each other, so my desktop was the odd one out.
timedatectl was my first stop:
$ timedatectl status
Local time: Sat 2025-01-04 08:11:01 PST
Universal time: Sat 2025-01-04 16:11:01 UTC
RTC time: Sat 2025-01-04 16:11:01
Time zone: America/Los_Angeles (PST, -0800)
System clock synchronized: no
NTP service: inactive
RTC in local TZ: no
Lines to note are System clock synchronized: no and NTP service: inactive, which implied nothing was adjusting the clock. When Linux boots, it grabs the time from the RTC (the battery-backed clock on the motherboard). Then it just ticks away with its own hardware timers. With no NTP running, nothing ever validates that count against another source.
RTC in local TZ: no was good news. That meant the hardware clock was already using UTC, which is what I want on Linux anyway. Done deal.
The solution was to enable time syncing, which turns on and starts systemd-timesyncd:
sudo timedatectl set-ntp true
timedatectl looked much better after a couple of packets:
$ timedatectl status
Local time: Sat 2025-01-04 08:18:42 PST
Universal time: Sat 2025-01-04 16:18:42 UTC
RTC time: Sat 2025-01-04 16:18:42
Time zone: America/Los_Angeles (PST, -0800)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
timedatectl timesync-status displays all the details:
$ timedatectl timesync-status
Server: 141.11.228.173 (0.arch.pool.ntp.org)
Poll interval: 34min 8s (min: 32s; max 34min 8s)
Leap: normal
Version: 4
Stratum: 2
Reference: 11FD0225
Precision: 1us (-26)
Root distance: 1.052ms (max: 5s)
Offset: +4.917ms
Delay: 81.811ms
Jitter: 3.721ms
Packet count: 8
Frequency: +4.873ppm
Here’s what some of the useful fields above mean:
Serveris the NTP server chosen from the pool. The IP address isn’t important.Poll intervalis how frequently the client requests the time. It begins at 32 seconds and expands as the local clock demonstrates consistency.Stratumis the distance from the source of time, for example how many hops away a server is from GPS hardware or a radio clock. A stratum 2 server means it’s synchronized from a stratum 1 server, which is typical for a desktop connected to the public internet.Root distanceis the server’s best guess as to its maximum error relative to that primary reference. It’s about a millisecond here, safely below the five-second threshold where timesyncd would change servers.Offsetis how far my clock is ahead or behind theirs. A few milliseconds is normal over the public internet.Delayis the round-trip time to the server. 82ms isn’t shocking for public NTP.Jitteris how much your samples differ from one another. Lower is better, and a few ms is good.Packet countis how many replies you’ve received from this server so far.
Leap indicates if a leap second is impending. Version is the NTP protocol version being used. Reference and Precision describe the server’s upstream source and its own clock. They’re mainly useful if you’re debugging the server itself.
This leaves us with Frequency, the ppm correction that the kernel has learned for the local oscillator. If the value is positive, the kernel is speeding the clock up. Left unchecked, the system clock would lose ~4.9 microseconds per second:
4.873 ppm * 86,400 seconds/day = 0.421 seconds/day
A slow clock would lag behind, but the desktop was ahead, so the additional minute had come from the RTC. That’s a separate crystal that keeps time when the machine is powered off, and each time the machine boots, its time is copied into the system clock. With no NTP running, nothing had been adjusting it either. RTC crystals are often rated at ±20ppm, or up to about 1.7 seconds per day, so a minute only takes a month or two to accrue.
While synchronized, the kernel writes the system time back to the RTC every 11 minutes. You can make it write now as well:
sudo hwclock --systohc --utc
Either way, after the next boot it starts off at the correct time rather than whatever the RTC had drifted to. With NTP enabled, the desktop checks in with the outside world just like the watch and phone do, and its offset is only a few milliseconds.