How can I tell if my Mac is keeping the clock updated properly?

Solution 1:

10.14 Mojave

Mojave still uses timed, but ntpdate and the helpers ntpq are removed. To check and update your system time, you can call sntp directly.

$ sudo sntp -sS pool.ntp.org
Password:
sntp [email protected] Tue Mar 21 14:36:42 UTC 2017 (136.200.1~2533)
2018-09-29 19:42:41.448103 (-0200) +1087.742403 +/- 725.183462 pool.ntp.org 188.68.36.203 s2 no-leap

Out of the box, a tracking file is missing. So if you get the error below when checking time:

kod_init_kod_db(): Cannot open KoD db file /var/db/ntp-kod: No such file or directory

create the file and change ownership to root. Some people reported this was actually breaking the ntp synchronization.

sudo touch /var/db/ntp-kod
sudo chown root:wheel /var/db/ntp-kod

Then run again to check if the error message is gone.

sudo sntp -sS pool.ntp.org

10.13 High Sierra

High Sierra uses timed, from /usr/libexec/timed, run by the system user _timed.

timed maintains system clock accuracy by synchronizing the clock with reference clocks via technologies like NTP. Inputs are merged inside of timed, where it calculates uncertainty to facilitate scheduling proactive time jobs. timed is also aware of power/battery conditions.

timed is managed by the LaunchDaemon /System/Library/LaunchDaemons/com.apple.timed.plist. timed runs…

  • when the daemon is loaded at boot (RunAtLoad: true)
  • every 3600 seconds (StartInterval: 3600)
  • when Airplane Mode is disabled (com.apple.systemconfiguration airplane mode changed: com.apple.radios.plist AirplaneMode false, which appears to be carried over from iOS)

You can see how 'off' your clock is by looking at the contents of /var/db/timed/com.apple.timed.plist, under the TMLastSystemTime dictionary in the TMTimeError key and the TMScaleFactorError key.

$ sudo defaults read /var/db/timed/com.apple.timed TMLastSystemTime
{
    TMCurrentTime = "537303485.281592";
    TMReliability = 1;
    TMRtcTime = "351422.381868388";
    TMScaleFactor = "0.9999958233107684";
    TMScaleFactorError = "3.468751755688052e-05";
    TMSource = TMTimeSynthesizer;
    TMTimeError = "0.6127951619022057";
}

Xcode screenshot of mentioned plist

timed uses the time server set in /etc/ntp.conf, which by default is

server time.apple.com

timed also uses TMTimeSynthesizer, something which CoreTime on iOS uses to update the clock with but I'm unaware of its history on macOS:

timed Sources

Don't run the timed binary yourself, as mentioned in the man page:

timed takes no arguments, and users should not launch it manually.

According to Apple Developer Forums user granada29 in the post ntpd, timed and chronyd in 10.13, timed performs the following:

timed appears to be a simple sntp client - i.e. it polls the NTP periodically (15 minutes) and uses the settimeofday() system call to set the sytem clock. I assume it has some cleverness to avoid stepping the clock backwards but there is no way to tell.

10.11 El Capitan to 10.12 Sierra

pacemaker is the daemon responsible for managing the time in macOS. It uses adjtime to adjust the clock per the content of /var/db/ntp.drift.

You can see how 'off' your clock is by looking at the contents of ntp.drift — for example, my file contains the following:

-23.640

This means that the clock is -23.64 PPM away from the time that it should be. The units of this number is PPM, or Parts Per Million. 1 PPM is 1 microsecond/second, or 3.6ms/h.

You can make the clock update more often by running pacemaker with the -a option, providing a time in seconds to wait between time movements:

/usr/libexec/pacemaker -a 10

To see the parameters being used by OS X for pacemaker, open /System/Library/LaunchDaemons/com.apple.pacemaker.plist.

{
    KeepAlive = { PathState = { "/private/var/db/ntp.drift" = :true; }; };
    Label = "com.apple.pacemaker";
    ProgramArguments = ( "/usr/libexec/pacemaker", "-b", "-e", "0.0001", "-a", "10" );
}

To find your current settings, run with the -i option:

/usr/libexec/pacemaker -i
Jan 19 18:20:08 g pacemaker[12544] <Info>: --- settings for external power ---
Jan 19 18:20:08 g pacemaker[12544] <Info>: interval = 1 seconds, tolerance = 0.000000, drift = -23.640000
Jan 19 18:20:08 g pacemaker[12544] <Info>: --- settings for internal power ---
Jan 19 18:20:08 g pacemaker[12544] <Info>: interval = 1 seconds, tolerance = 0.000024, drift = -23.640000

You can show the log by running with the -v option:

sudo /usr/libexec/pacemaker -v
Password:
Jan 19 18:23:17 g pacemaker[13202] <Info>: power status check: using external power
Jan 19 18:23:17 g pacemaker[13202] <Info>: created file monitor for /var/db/ntp.drift
Jan 19 18:23:17 g pacemaker[13202] <Info>: interval = 1 seconds, tolerance = 0.000000, drift = -23.640000
Jan 19 18:23:19 g pacemaker[13202] <Debug>: drift -23.640000 residue 0.000000 delta -23
Jan 19 18:23:20 g pacemaker[13202] <Debug>: drift -23.640000 residue -0.640000 delta -24
Jan 19 18:23:21 g pacemaker[13202] <Debug>: drift -23.640000 residue -0.280000 delta -23
Jan 19 18:23:22 g pacemaker[13202] <Debug>: drift -23.640000 residue -0.920000 delta -24
Jan 19 18:23:23 g pacemaker[13202] <Debug>: drift -23.640000 residue -0.560000 delta -24
Jan 19 18:23:24 g pacemaker[13202] <Debug>: drift -23.640000 residue -0.200000 delta -23
⌃C%

Solution 2:

If you go to http://time.gov you can see the official time (up to the second) and use that to verify if your system time is correct or not. Note that this is the official NIST time, and does its own synchronization in the browser, independently of the system time (as an example, you can see here that time.gov handles leap seconds, whereas OS X apparently does not).

Solution 3:

Starting with High Sierra the ntpd system daemon was replaced with the timed system daemon which invokes /usr/libexec/timed.

The best exec I've found to get details is systemsetup (run as root) with its various flags:

[-getusingnetworktime] [-setusingnetworktime on | off]
[-getnetworktimeserver] [-setnetworktimeserver timeserver]

The resulting output is by far less verbose (= boring). E.g no ∂T/drift details.

Apparently timed uses only one ntp-server (the first one listed - checked with WireShark/LittleSnitch) even if several are entered in the system preferences/ntp.conf file.

Further reading (not very technical): Has anyone got the time? How High Sierra has changed time synchronisation


A legacy ntpd daemon is still present but unloaded. It can be loaded though by entering in Terminal.app:

sudo launchctl load [-F|-w] /System/Library/LaunchDaemons/org.ntp.ntpd-legacy.plist

in SIP disabled mode. Entering ntpq -p will work again then.

To load the daemon in SIP enabled mode copy the file to /Library/LaunchDaemons/:

sudo cp /System/Library/LaunchDaemons/org.ntp.ntpd-legacy.plist /Library/LaunchDaemons/org.ntp.ntpd.plist

Modify the label of the plist with nano or another editor from org.ntp.ntpd-legacy to org.ntp.ntpd:

sudo nano /Library/LaunchDaemons/org.ntp.ntpd.plist

Load the daemon:

sudo launchctl load -w /Library/LaunchDaemons/org.ntp.ntpd.plist

If I find a better exec to get time details with the default High Sierra daemon the answer will be updated.