The goal of ntpclient is not only to set your computer's clock right once, but keep it there. First, a note on typical 1990's and 2000's computer crystals. They are truly pathetic. A "real" crystal oscillator (TCXO) usually has an initial set error of less than 5 ppm, and variation over time, voltage, and temperature measured in tenths of a ppm (and an OCXO can reach ±0.3 ppm stability over ten years and 85°C temperature swing). The devices used in conventional PC motherboards and single board computers, however, often have initial set errors up to 150 ppm, and will vary 5 ppm over the course of a day-night cycle in a pseudo-air-conditioned space. [Operating system software can sometimes exacerbate the problem. I have seen some i686 Red Hat 7.3 systems run the clock at 512 Hz, or 953 microseconds per tick, giving a built in 64 ppm error. Even the normally exemplary DEC Alpha has, when run with Linux, a truly awful calibration scheme; Linux runs it with a nominal ticks per second of 1024, which gives a tick value of 977, theoretical additional error -448 ppm, actual frequency observed -443.7 ppm.] Still, the pattern is clear: the first and largest error of a crystal is its initial set error. I strongly urge the calibration of each computer, and storing its frequency error in a non-volatile medium, before you do anything else with time setting and locking. While you could do it in a few seconds using an accurate frequency counter, below I show a software-only method using ntpclient and a high quality NTP server. To perform the activities described, you need a way to control and monitor your system's clock -- both its frequency and value. On Linux, the kernel API is described in adjtimex(2). There are two programs that I know of that provide shell-level access to this interface, both called adjtimex(1). One is written by Steven Dick and Jim Van Zandt, see the adjtimex* files in http://metalab.unc.edu/pub/Linux/system/admin/time/ It uses long options, and includes some interesting functionality beyond the basic exposure of adjtimex(2). I (Larry Doolittle) wrote the other; it uses short options, and has no bloat^H^H^H^H^Hextra features. I include the code here for a standalone version; it is also incorporated into busybox (http://www.busybox.net), although you may have to select it at compile time, like any other component. Fortunately (and not coincidentally) the core functions of the two adjtimex programs can be used interchangeably, as long as you only use the short option variant of the Dick/Van Zandt adjtimex. The options discussed here are: -f frequency (integer kernel units) -o time offset in microseconds -t kernel tick (microseconds per jiffy) First, set the time approximately right, as root: ntpclient -s -h $NTPHOST You should see a single line printed like 36765 4980.373 1341.0 39.7 956761.4 839.2 0 Get used to this line: column headers are 1. day since 1900 2. seconds since midnight 3. elapsed time for NTP transaction (microseconds) 4. internal server delay (microseconds) 5. clock difference between your computer and the NTP server (microseconds) 6. dispersion reported by server (microseconds) 7. your computer's adjtimex frequency (ppm * 65536) So in the example above, your computer's clock was a bit more than 0.95 seconds fast, compared to the clock on $NTPHOST. Now check that the clock setting worked. ntpclient -c 1 -h $NTPHOST 36765 4993.512 1345.0 40.9 3615.3 839.2 0 So now the time difference is only a few milliseconds. On to measure the frequency calibration for your system. If you're in a hurry, it's OK to only spend 20 minutes on this step. ntpclient -i 60 -c 20 -h $NTPHOST >$(hostname).ntp.log & Otherwise, you will learn much more about your system and its communication with the NTP server by letting the log run for 24 hours. ntpclient -i 300 -c 288 -h $NTPHOST >$(hostname).ntp.log & Things to watch for in the above log: If the last column (kernel frequency fine tune) ever changes, you haven't turned off other time adjustment programs. AFAIK the only programs around that would move this number are ntpclient and xntpd. On most out-of-the-box systems, that last column should start zero and stay zero. Use gnuplot to plot the resulting file as follows: plot "HOSTNAME.ntp.log" using (($1-36765)*86400+$2):5:($3+$6) with yerrorbars This shows time error (microseconds) as a function of elapsed time (seconds). The error bars show the uncertainty in the measurement. Ideally, it would be a smooth, straight line, where the slope represents the frequency error of your crystal. If an occasional point is both off-center and has a large error bar, it shows a transaction got delayed somewhere in the process, either inside the server, or one of the two UDP packet propagation steps. This is normal, and ntpclient can deal with those quite well. If points are not evenly spaced on the horizontal axis, packets were actually lost; this is less common, but still OK. If the error bar becomes suddenly large, and takes a few minutes to slowly recover, your NTP host (presumably xntpd) had problems communicating with _its_ server, and reported that problem to you by increasing its "dispersion" (this is a hack, required by xntpd's core incorrect assumption that errors in network delays have Gaussian statistics; ntpclient does not have this flaw). If there are sudden large, persistent steps in error, some other program is making step changes to time. Check for, e.g., ntpdate run as a cron job. If your client machine is OK, check for problems on the _host_ machine. Assuming the graph above is clean, and has non-garbled data for the first and last points, you can run it through the enclosed awk script (rate.awk) to determine the appropriate frequency value. $ awk -f rate.awk some_log_file The second line makes explicit the retries that may be required for this UDP-based time protocol. If the first time request takes longer than 10000 microseconds to resolve, or the packets get lost, it instructs ntpclient to try again 15 seconds later (the minimum retry period mandated by RFC-4330), and it won't exit until it gets such a suitable response. As of 2006, ntpclient can in theory combine the three lines above into one: ntpclient -f $NONVOLATILE_MEMORY_VALUE -s -l -i 600 -g 10000 -h $NTPHOST >some_log_file This can streamline the startup process, since you may be able to avoid a layer of shell scripting. On the other hand, it is less tested, and there is no (current) means to independently set the packet interval for the set and lock phases. It's an interesting question how sensitive the boot process should be to the time set process. If you have a battery backed hardware clock, there's not much problem running for a while without a network-accurate system clock. In that case you could put both ntpclient commands into a background script, and the only possible issue is the sudden (but probably small) warp of the clock at the indefinite time in the boot sequence when ntpclient gets its acceptable answer. On the other hand, some embedded computers have no clue what time it is until the network responds. Any files created will be marked Jan 1 1970, and other application-dependent issues may arise if there is a nonsense time on the system during later parts of the boot sequence. Then you may well want to enforce completion of the first ntpclient before starting your application. If this is too drastic for you, and you want a fallback mode when the time server is dead, add a "-c 5" switch to the end of that ntpclient command, giving at most 5 retries, if something goes wrong with the time set. For that approach to be useful, consider patching the source to lower the minimum packet send interval from the RFC-4330-mandated 15 seconds.