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

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%

This answer applies only to 10.12 Sierra and lower.

The details may be helpful for reference, but another answer covers newer macOS timekeeping details excellently.


The first step is to see if your time is set up.

Mac:~ me$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*time.apple.com  17.168.198.149   2 u 1046  512   37   58.475    9.477   3.674

Assuming you have delay/offset/jitter values less than 100 (delay could be less than 1000 in normal situations for less time-accurate-critical systems), the next command to run in terminal is ntpq followed by the timeserver from your ntpq and system preference. You can also test other time servers to see if they have lower delays since the timekeeping system likes to have a close, fast response from time servers when correcting the time for millisecond differences and calculating how the current hardware clock is drifting away from the standard time.

Mac:~ me$ ntpdate -q time.apple.com
server 17.151.16.12, stratum 2, offset 0.081698, delay 0.11237
server 17.151.16.20, stratum 2, offset 0.081365, delay 0.11310
server 17.151.16.21, stratum 2, offset 0.082754, delay 0.11440
server 17.151.16.22, stratum 2, offset 0.081750, delay 0.11264
server 17.151.16.23, stratum 2, offset 0.082691, delay 0.11415
server 17.151.16.38, stratum 2, offset 0.082077, delay 0.11458
server 17.171.4.13, stratum 2, offset 0.084822, delay 0.08054
server 17.171.4.14, stratum 2, offset 0.083749, delay 0.08142
server 17.171.4.15, stratum 2, offset 0.086343, delay 0.07605
server 17.171.4.33, stratum 2, offset 0.086526, delay 0.07690
server 17.171.4.34, stratum 2, offset 0.084500, delay 0.07997
server 17.171.4.35, stratum 2, offset 0.083987, delay 0.08278
server 17.171.4.36, stratum 2, offset 0.084382, delay 0.08028
server 17.171.4.37, stratum 2, offset 0.085948, delay 0.07831
server 17.151.16.14, stratum 2, offset 0.082043, delay 0.11270
19 Jan 12:09:32 ntpdate[4592]: adjust time server 17.171.4.15 offset 0.086343 sec
Mac:~ me$ ntpq
ntpq> assoc

ind assid status  conf reach auth condition  last_event cnt
===========================================================
  1 57788  9014   yes   yes  none    reject   reachable  1
ntpq> peer
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 time.apple.com  17.168.198.148   2 u  729  512    1  133.274   51.653 371.362
ntpq> q

The next thing to check is your pacemaker program:

Mac:~ me$ ps -ef|grep [p]acemaker
0    76     1   0 Fri08AM ??         0:03.64 /usr/libexec/pacemaker -b -e 0.0001 -a 10

This shows that on battery, the adjust interval is no more than once every 10 seconds and adjusting even less if the clock error is less than 0.1 millisecond.

If you find that your offset is seconds or more, you might want to change the timeservers you use or perhaps change the values used on pacemaker to use more energy and CPU but have a clock closer to the true time in exchange for the settings Apple has shipped with 10.9.

  • How can I keep my system clock in sync under Mavericks?
  • ntpd not updating time
  • ntpd: consistently incorrect time on mid-2013 MacBook Air

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.