Vivian Voss

One Clock, One Tool, Three Distros

freebsd linux unix devops

The Unix Way ■ Episode 15

Ask a Linux admin which time daemon their server runs. Pause for the silence. Then watch them check three different places to find out. On FreeBSD the question does not arise.

This is not a story about clocks. It is a story about how a basic system service ended up with three implementations, three default behaviours, three configuration files, and zero agreement, and what it costs the people who have to administer the result.

A Short History of NTP

The Network Time Protocol was designed by David L. Mills at the University of Delaware in 1985. RFC 958 standardised the original protocol; RFC 1305 codified version 3 in 1992; RFC 5905 finalised version 4 in 2010. The reference implementation, called ntpd, was written by Mills and his students alongside the protocol itself. For most of the next thirty years, ntpd was the only serious option for synchronising the clock on a Unix machine. The University of Delaware NTP code became the reference, the documentation, and the default.

The protocol matters because it is harder than it looks. A client cannot simply ask a server "what time is it" and accept the answer; the round-trip introduces latency, the network jitters, the local clock drifts at a rate that depends on temperature and load, and the only way to compute a useful offset is to query several servers, weigh their replies against each other, and apply a clock-discipline algorithm that gradually steers the local oscillator without abrupt jumps. The full NTP protocol embeds this into the daemon. The Simple Network Time Protocol, SNTP, is the same wire format used naively: query one server, accept one answer, set the clock.

FreeBSD: One Tool, In Base

ntpd(8) has been part of the FreeBSD base system since 4.x in 2000. To enable it, an administrator adds a single line to /etc/rc.conf:

ntpd_enable="YES"

The configuration file /etc/ntp.conf is shipped with sensible defaults pointing at the FreeBSD pool servers; non-default servers can be added by editing it. The service is started with service ntpd start. The diagnostic command is ntpq -p, which prints the list of configured peers, their measured offsets, and the daemon's current opinion about which it is using.

For the rare case where the in-base ntpd does not fit, OpenNTPD is available in ports under net/openntpd. The most common reason to reach for it is jails: the OpenBSD-derived OpenNTPD is more comfortable binding to specific addresses, which matters when a jail wants its own NTP daemon listening on its own IP. For ninety-nine servers out of a hundred, the in-base ntpd is the answer, and the answer has not changed in over twenty years.

The reason this is unremarkable on FreeBSD is the reason most things on FreeBSD are unremarkable: a single team makes the decisions and maintains the result. The base system includes ntpd. The base system documents ntpd. The base system upgrades ntpd. There is no second opinion, because there is no second team.

Linux: ntpd, the Original

The same ntpd from David L. Mills was, for most of Linux's existence, the standard time daemon on Linux too. Distributions packaged it under names like ntp (Debian, Ubuntu) or ntp (RHEL, Fedora). The configuration file was /etc/ntp.conf, the service was ntpd, the diagnostic was ntpq -p. The world worked.

By the late 2010s, the consensus had begun to shift. The ntpd codebase had a complicated history of maintenance, several serious CVEs, and a configuration syntax that newer admins found rather opaque. The Linux Foundation funded a separate "Network Time Foundation" maintenance effort which kept the lights on but did not modernise the daemon in ways that distributions wanted. By 2026, every major distribution has moved on. ntpd is still installable, still works, and is still a perfectly reasonable choice for an administrator who knows it. It is no longer what new servers ship with.

Linux: chrony, the Modern Replacement

Richard Curnow began work on chrony in 1997, originally as a personal project for synchronising laptops with intermittent network connectivity. After Curnow stepped back from active development, Miroslav Lichvar at Red Hat picked it up, and chrony is now developed under Red Hat sponsorship. By 2026 it is the default time daemon on Fedora, RHEL, CentOS Stream, Rocky, Alma, openSUSE, and Arch.

chrony is a complete NTP implementation. It can act as a client, a server, or both. It supports NTS (Network Time Security, RFC 8915) for authenticated time without the operational burden of NTP autokey. It converges faster than ntpd on first start, handles long network outages without drifting badly, and behaves better on virtual machines whose hardware clock cannot be trusted. The configuration file is /etc/chrony.conf on RHEL-family systems and /etc/chrony/chrony.conf on Debian-family systems, because packagers disagreed on the right path. The daemon is chronyd. The diagnostic is chronyc tracking (current sync state) and chronyc sources (list of upstream servers). The service unit is sometimes chronyd, sometimes chrony, depending on which packaging tradition the distribution inherited.

If a Linux admin is asked to set up time synchronisation on a server in 2026 and given a free hand, the answer is almost always chrony. The accuracy is better, the codebase is healthier, the maintainer is responsive, and the documentation is current.

Linux: systemd-timesyncd, the Minimalist

The third answer was added by systemd in version 213 (December 2014). systemd-timesyncd is not a full NTP implementation; it is an SNTP client. It queries one server at a time, accepts the answer, and sets the clock. It does not triangulate from multiple sources, it does not weight peers against each other, it does not detect a single misconfigured upstream lying about the time. It is also small, simple, and adequate for the case it was built for: a desktop or a container that just needs the clock to be roughly right.

Ubuntu adopted systemd-timesyncd as the default in 18.04 (2018) and has kept it as the desktop default ever since; Ubuntu Server installs chrony by default in newer releases but systemd-timesyncd was the documented standard for several LTS cycles. Many container images use systemd-timesyncd because it has fewer dependencies than chrony. The configuration file is /etc/systemd/timesyncd.conf, the status command is timedatectl status, and the daemon is part of systemd itself rather than a separate package.

The trap with systemd-timesyncd is that it ignores /etc/ntp.conf. An administrator who inherits a server, sees /etc/ntp.conf with carefully tuned upstream servers, and assumes those servers are being used, may well be wrong: if systemd-timesyncd is the active daemon, it is reading /etc/systemd/timesyncd.conf, and /etc/ntp.conf is decoration. The diagnostic for "which daemon is actually running" on a Linux box is to enumerate the candidates: systemctl status chronyd, systemctl status ntpd, systemctl status systemd-timesyncd, until one of them returns "active". Two of them sometimes do. That conversation is its own kind of fun.

Three Daemons, Three Defaults, Three Diagnostics since scope config daemon diagnostic default on ntpd David L. Mills 1985 full NTP /etc/ntp.conf ntpd ntpq -p FreeBSD base since 2000 chrony Curnow / Red Hat 1997 full NTP + NTS /etc/chrony.conf or /etc/chrony/chrony.conf chronyd chronyc tracking chronyc sources RHEL, Fedora, Arch, openSUSE timesyncd systemd 2014 SNTP only no triangulation /etc/systemd/ timesyncd.conf systemd-timesyncd timedatectl status Ubuntu desktop since 18.04 Same problem on Linux, three answers. On FreeBSD: one row of the table covers the case.

OpenNTPD, the Quiet One

A footnote, but worth one. OpenNTPD was written by Henning Brauer for OpenBSD in 2003, motivated by the same complaints about the reference ntpd that eventually drove Linux distributions toward chrony: complicated configuration, a hard-to-audit codebase, and licensing that did not fit OpenBSD's standards. OpenNTPD is included in OpenBSD base, and is available on FreeBSD via the net/openntpd port. It is a deliberately small full-NTP implementation, with a configuration file the size of a postcard. For administrators who want a simple time daemon without the size of ntpd and without depending on chrony, OpenNTPD is the quiet third option that has worked steadily for over twenty years.

The Point

The same problem (the clock drifts, set it from a network source) has three answers on Linux because three different communities, working on overlapping but not identical use cases, arrived at three different daemons, and the distributions that integrate them could not converge on a single recommendation. Fedora chose chrony. Ubuntu chose systemd-timesyncd for the desktop and chrony for the server. Debian sat on ntpd for years before transitioning. Arch let the user decide.

The Cost of Three Answers FreeBSD one team one decision one config file one diagnostic unchanged since 2000 Linux three communities three defaults by distribution three config paths three diagnostics paid every time an admin inherits a server

FreeBSD did not have that argument. The base team picked ntpd, kept it for two decades, and the rest of the system was built around the choice. When OpenNTPD became available, it went into ports as a clearly-labelled alternative; it did not displace the in-base default.

The cost of three answers is paid every time a new admin inherits a Linux server and has to discover which daemon is currently running, which config file it is reading, and which it ought to be reading. The cost of one answer is a config file you have already seen, on a system you have already learned.

This is not a question of which daemon is best. chrony is, by most measures, the best of the four. The question is what it costs to need to know that, every time, on every system, in a way that varies by distribution and by year. On FreeBSD the answer to "what time daemon does this server run" is in /etc/rc.conf, has been since 2000, and is the same on the next server too.

NTP since 1985 by David L. Mills. ntpd in FreeBSD base since 4.x in 2000, one line in /etc/rc.conf, diagnostic ntpq -p, unchanged for twenty-five years. On Linux: ntpd the original (legacy by 2026), chrony by Curnow and Red Hat (default on Fedora/RHEL/Arch), and systemd-timesyncd the SNTP minimalist (default on Ubuntu since 18.04, ignores /etc/ntp.conf). Three answers because three groups disagreed and the distribution committees could not converge. The cost of three answers is paid every time an admin inherits a server.