FreeBSD NTP Free-running Oscillator Experiment

An exploration of using a NTP server with no (or limited) external reference

The Network Time Protocol daemon is designed to run both as a server and a client program, synchronizing the clock of a computer to an external reference, either over a communications network or connected directly to some sort of clock. But what would happen if one ran a NTP server with no time reference except the computers internal clock? This is supported by ntpd, primarily to allow ntpd to be used with other time synchronization programs that don't communicate with the NTP daemon directly. Using the internal clock in a 'free-running' (non synchronized) mode is not encouraged by the developers of NTP, mostly because the accuracy of standard PC hardware clocks is poor when compared to modern time-keeping hardware.

Ntpd keeps track of the frequency error of the local oscillator in the computer by measuring the difference in time between the local system and the reference clock. It then uses this frequency error (called the 'drift') to adjust the local clock rate and thus compensate for the error. This error value is expressed in parts-per-million, and is stored in a file designated by the ntpd configuration. The administrator discouraged from editing this file directly, but it can be used to adjust the clock drift directly if the administrator is careful.

The drift value changes as the drift rate of the oscillator changes. This is mostly due to temperature and power supply fluctuations in the short term, and can change long-term as the crystal in the oscillator ages. The purpose of this experiment was to see if the drift rate could be measured well enough that an average value could be calculated that would keep the oscillator running accurately for reasonably short time periods.

Setup:
The server in question was an eMachine etower 333C, with a Cyrix 6x86MX (250.06-MHz 686-class CPU), 163840K bytes RAM, 15 GB Western Digital HD, running FreeBSD 4.9, and Ntpd 4.1.0

This system was a retired production NTP server, originally synchronized via a GPS receiver. Ntpd was reconfigured to run with the LOCAL driver, synchronized with a stratum-1 NTP server via the 'ntpdate' command, and let run for 46 days. The NTP stratum number of the system was adjusted down so that any systems that found it would not try to use it as a master clock, and the NTP time it served was monitored and measured against three networked stratum-1 servers.

A perl script was written to extract the amount of drift the server displayed during the experiment. Here is the data:

20081108: Delta offset: 0.363216401 ppm: 4.20389353009259 min_offset: 0.079749758 max_offset: 0.442966159
20081109: Delta offset: 0.374144162 ppm: 4.33037224537037 min_offset: 0.444830862 max_offset: 0.818975024
20081110: Delta offset: 0.388127166 ppm: 4.49221256944444 min_offset: 0.818975024 max_offset: 1.207102190
20081111: Delta offset: 0.384203207 ppm: 4.44679637731481 min_offset: 1.207102190 max_offset: 1.591305397
20081112: Delta offset: 0.381238571 ppm: 4.41248346064815 min_offset: 1.591305397 max_offset: 1.972543968
20081113: Delta offset: 0.389499521 ppm: 4.50809630787037 min_offset: 1.972543968 max_offset: 2.362043489
20081114: Delta offset: 0.389539037 ppm: 4.50855366898148 min_offset: 2.362043489 max_offset: 2.751582526
20081115: Delta offset: 0.388816263 ppm: 4.50018822916666 min_offset: 2.751582526 max_offset: 3.140398789
20081116: Delta offset: 0.392243414 ppm: 4.53985432870370 min_offset: 3.141234169 max_offset: 3.533477583
20081117: Delta offset: 0.397508941 ppm: 4.60079792824074 min_offset: 3.534686834 max_offset: 3.932195775
20081118: Delta offset: 0.392385400 ppm: 4.54149768518519 min_offset: 3.932765614 max_offset: 4.325151014
20081119: Delta offset: 0.396723285 ppm: 4.59170468749999 min_offset: 4.325151014 max_offset: 4.721874299
20081120: Delta offset: 0.397819415 ppm: 4.60439137731482 min_offset: 4.722001505 max_offset: 5.119820920
20081121: Delta offset: 0.394544727 ppm: 4.56648989583333 min_offset: 5.119820920 max_offset: 5.514365647
20081122: Delta offset: 0.396518580 ppm: 4.58933541666667 min_offset: 5.514365647 max_offset: 5.910884227
20081123: Delta offset: 0.400085207 ppm: 4.63061582175926 min_offset: 5.910884227 max_offset: 6.310969434
20081124: Delta offset: 0.399661764 ppm: 4.62571486111110 min_offset: 6.310969434 max_offset: 6.710631198
20081125: Delta offset: 0.391563405 ppm: 4.53198385416667 min_offset: 6.710631198 max_offset: 7.102194603
20081126: Delta offset: 0.391811264 ppm: 4.53485259259259 min_offset: 7.102194603 max_offset: 7.494005867
20081127: Delta offset: 0.398619859 ppm: 4.61365577546296 min_offset: 7.495293617 max_offset: 7.893913476
20081128: Delta offset: 0.392883309 ppm: 4.54726052083334 min_offset: 7.893913476 max_offset: 8.286796785
20081129: Delta offset: 0.395233530 ppm: 4.57446215277778 min_offset: 8.286796785 max_offset: 8.682030315
20081130: Delta offset: 0.393590590 ppm: 4.55544664351852 min_offset: 8.682583781 max_offset: 9.076174371
20081201: Delta offset: 0.392250873 ppm: 4.53994065972222 min_offset: 9.076174371 max_offset: 9.468425244
20081202: Delta offset: 0.395582705 ppm: 4.57850353009258 min_offset: 9.468425244 max_offset: 9.864007949
20081203: Delta offset: 0.391896521 ppm: 4.53583936342594 min_offset: 9.864007949 max_offset: 10.255904470
20081204: Delta offset: 0.394109528 ppm: 4.56145287037037 min_offset: 10.255904470 max_offset: 10.650013998
20081205: Delta offset: 0.392407010 ppm: 4.54174780092592 min_offset: 10.650013998 max_offset: 11.042421008
20081206: Delta offset: 0.383782794 ppm: 4.44193048611111 min_offset: 11.042421008 max_offset: 11.426203802
20081207: Delta offset: 0.391153018 ppm: 4.52723400462964 min_offset: 11.426203802 max_offset: 11.817356820
20081208: Delta offset: 0.391782629 ppm: 4.53452116898148 min_offset: 11.817879045 max_offset: 12.209661674
20081209: Delta offset: 0.390606176 ppm: 4.52090481481482 min_offset: 12.210263520 max_offset: 12.600869696
20081210: Delta offset: 0.402038776 ppm: 4.65322657407407 min_offset: 12.600869696 max_offset: 13.002908472
20081211: Delta offset: 0.398102680 ppm: 4.60766990740742 min_offset: 13.002908472 max_offset: 13.401011152
20081212: Delta offset: 0.396956409 ppm: 4.59440288194444 min_offset: 13.401011152 max_offset: 13.797967561
20081213: Delta offset: 0.392624034 ppm: 4.54425965277779 min_offset: 13.799509270 max_offset: 14.192133304
20081214: Delta offset: 0.355670876 ppm: 4.11656106481481 min_offset: 14.192133304 max_offset: 14.547804180
20081215: Delta offset: 0.379115759 ppm: 4.38791387731481 min_offset: 14.547804180 max_offset: 14.926919939
20081216: Delta offset: 0.404047781 ppm: 4.67647894675927 min_offset: 14.926919939 max_offset: 15.330967720
20081217: Delta offset: 0.397342178 ppm: 4.59886780092591 min_offset: 15.330967720 max_offset: 15.728309898
20081218: Delta offset: 0.402789974 ppm: 4.66192099537038 min_offset: 15.729432273 max_offset: 16.132222247
20081219: Delta offset: 0.392841710 ppm: 4.54677905092591 min_offset: 16.133105872 max_offset: 16.525947582
20081220: Delta offset: 0.392435371 ppm: 4.54207605324071 min_offset: 16.526347253 max_offset: 16.918782624
20081221: Delta offset: 0.379558080 ppm: 4.39303332175929 min_offset: 16.918782624 max_offset: 17.298340703
20081222: Delta offset: 0.387561743 ppm: 4.48566832175925 min_offset: 17.298340703 max_offset: 17.685902446

Experiment runtime: 46 days
Max offset measured from reference clocks: 17.987426589 seconds
The clock drift that ntpd was using in this case was 97.237 ppm. This was a left-over from when the system was a stratum-1 NTP server, with GPS connected. During this experiment however, the system had been moved to a climate-controlled machine room with no GPS receiver connected. Even if the drift rate had been correct before, the change in temperature probably explains the different drift rate.

Phase 2:
Having established that a fairly constant drift rate was exhibited by the free-running oscillator server, the next step was to fine-tune the drift rate to the servers new environment. To accomplish this the ntpd configuration was changed to synchronize the system to three stratum-1 NTP servers, and to record the drift value once per hour. The server was left to run for 120 hours to settle the new drift rate, and an average value for the rate was calculated from the last 24 hours of data gathered.

Phase 3:
The new daily drift rate, 92.648 ppm, was placed in the ntp.drift file, the ntpd configuration was changed back to the LOCAL driver (free-running local oscillator), the clock was set to one of the stratum-1 servers via 'ntpdate', and the ntpd program was restarted. New data was collected with the system monitoring the free-running system vs. the network NTP servers. This data showed a much more accurate clock rate:

20090102.hilo.txt: Delta offset: -0.002954424, ppm: -0.0341947222222222, min_offset: 0.004874786, max_offset: 0.001920362
20090103.hilo.txt: Delta offset: 0.002785164, ppm: 0.0322356944444444, min_offset: 0.001966971, max_offset: 0.004752135
20090104.hilo.txt: Delta offset: 0.00460516, ppm: 0.053300462962963, min_offset: 0.004837790, max_offset: 0.009442950
20090105.hilo.txt: Delta offset: 0.002063145, ppm: 0.0238789930555555, min_offset: 0.009442950, max_offset: 0.011506095
20090106.hilo.txt: Delta offset: -0.000601556, ppm: -0.0069624537037037, min_offset: 0.011506095, max_offset: 0.010904539
20090107.hilo.txt: Delta offset: 0.002149115, ppm: 0.0248740162037037, min_offset: 0.010904539, max_offset: 0.013053654
20090108.hilo.txt: Delta offset: -0.002688654, ppm: -0.0311186805555556, min_offset: 0.013053654, max_offset: 0.010365000
20090109.hilo.txt: Delta offset: -0.00815062, ppm: -0.0943358796296296, min_offset: 0.010365000, max_offset: 0.002214380
20090110.hilo.txt: Delta offset: 0.003651799, ppm: 0.0422661921296296, min_offset: 0.002214380, max_offset: 0.005866179
20090111.hilo.txt: Delta offset: 0.002283818, ppm: 0.0264330787037037, min_offset: 0.005866179, max_offset: 0.008149997
20090112.hilo.txt: Delta offset: -0.000508651000000001, ppm: -0.00588716435185186, min_offset: 0.008149997, max_offset: 0.007641346
20090113.hilo.txt: Delta offset: 0.006502467, ppm: 0.0752600347222222, min_offset: 0.007641346, max_offset: 0.014143813
20090114.hilo.txt: Delta offset: -0.002838319, ppm: -0.0328509143518519, min_offset: 0.014143813, max_offset: 0.011305494
20090115.hilo.txt: Delta offset: -0.001488361, ppm: -0.0172264004629629, min_offset: 0.011305494, max_offset: 0.009817133
20090116.hilo.txt: Delta offset: 0.004578027, ppm: 0.0529864236111111, min_offset: 0.009817133, max_offset: 0.014395160
20090117.hilo.txt: Delta offset: -0.002998668, ppm: -0.0347068055555556, min_offset: 0.014432744, max_offset: 0.011434076
20090118.hilo.txt: Delta offset: 0.003404826, ppm: 0.0394077083333333, min_offset: 0.011419894, max_offset: 0.014824720
20090119.hilo.txt: Delta offset: 0.003414708, ppm: 0.0395220833333333, min_offset: 0.014802727, max_offset: 0.018217435
20090120.hilo.txt: Delta offset: 0.002722521, ppm: 0.0315106597222222, min_offset: 0.018217435, max_offset: 0.020939956
20090121.hilo.txt: Delta offset: 0.002246066, ppm: 0.0259961342592593, min_offset: 0.020939956, max_offset: 0.023186022
20090122.hilo.txt: Delta offset: 0.005873647, ppm: 0.0679820254629629, min_offset: 0.023186022, max_offset: 0.029059669
20090123.hilo.txt: Delta offset: -0.001396524, ppm: -0.0161634722222222, min_offset: 0.029059669, max_offset: 0.027663145
20090124.hilo.txt: Delta offset: -0.001538165, ppm: -0.0178028356481482, min_offset: 0.027663145, max_offset: 0.026124980
20090125.hilo.txt: Delta offset: -0.002903204, ppm: -0.0336018981481481, min_offset: 0.026124980, max_offset: 0.023221776
20090126.hilo.txt: Delta offset: -0.000805219999999999, ppm: -0.00931967592592591, min_offset: 0.023221776, max_offset: 0.022416556

At the end of 24 days of free-running, the clock in the server had slipped no more than ~0.03 seconds from time reported by stratum-1 synchronized clocks. This highest error rate recorded in the stats is ~0.094 ppm, which is outstanding for an ordinary crystal oscillator. The time offset from the synchronized clocks varied from positive to negative during the experiment, indicating that the variation in the clock was still there, but that the calibrated drift rate was close enough to the actual drift rate that the time stayed quite close to the actual time reported by the reference clocks.

What is the point of this? The investigator has heard of isolated local area networks running NTP time servers in a configuration such as this. A well-tuned drift value in a server in a climate-controlled environment could be used in such a setup, provided that the time on the server was manually updated frequently enough that the offset from the actual time never exceeded a given amount. This would of course depend on the needs of the users of such a network compared to the costs and practicality of installing a reference clock such as a GPS or long-wave radio receiver. The point was to determine how difficult it would be to hand-tune a free-running NTP server for a reasonable level of accuracy over modest run intervals. While this experiment shows this is fairly easy given a stable climate-controlled environment and access to NTP reference clocks initially, in practise better results are always achieved by running ntpd as intended: synchronizing system time against an ensamble of NTP servers with hardware reference clocks attached.

Links:
http://www.prc68.com/I/PClock.shtml
http://support.ntp.org/bin/view/Support/HowToCalibrateSystemClockUsingNTP