⏱️ Reading time: 11 min
RFC 5905, the document that defines version 4 of the NTP protocol, was published in June 2010 and has since been updated by RFC 7822, 8573, 9109, 9748, and 9769, yet it still runs on billions of routers, servers, and phones. Every time a laptop connects to a new network and adjusts its clock by milliseconds without asking, that’s NTP working silently behind that synchronization.
📑 En este artículo
- TL;DR
- What is the NTP protocol?
- Why time synchronization matters
- How NTP works under the hood
- Practical examples and how to get started
- Real-world use cases
- Common mistakes and best practices
- Comparison: NTP versus other ways to synchronize the clock
- Going deeper: security and advanced precision
- Frequently Asked Questions
- References
This article explains how that synchronization works, from the stratum hierarchy to the exact calculation of the offset between two clocks, along with the commands to verify it on Linux.
TL;DR
- UDP 123 is the port NTP uses to exchange the four timestamps that calculate the clock offset
- chronyc tracking shows the stratum, offset, and frequency drift of the local clock in a single output
- Strata number the distance to the reference: stratum 0 is atomic clocks or GPS, stratum 1 is the first tier of servers
- RFC 8915 defines NTS, the extension that authenticates the received time without exposing the encryption key
- systemd-timesyncd and chrony should not run together: they compete for control of the system clock
What is the NTP protocol?
NTP is a network protocol that synchronizes a device’s clock with an external time reference, using a hierarchy of servers called strata. Designed by David L. Mills in 1985 and described in RFC 5905, the NTP protocol corrects the accumulated drift of the local clock against a more precise source.
The hierarchy is organized into strata: stratum 0 groups reference clocks like GPS or cesium; stratum 1, the servers connected directly to those clocks; and so on down to clients at higher strata, which only adjust their own time without offering service to anyone else. Stratum 15 is the limit declared by the standard; stratum 16 marks an unsynchronized clock.
Why time synchronization matters
Without a shared clock, a distributed system can’t order events, sign certificates, or replicate data consistently. The NTP protocol solves that underlying problem: it gives each machine a notion of time close enough to its neighbors’ so that systems depending on timestamps (TLS, Kerberos, distributed databases, blockchains with time stamps) work without friction.
A TLS certificate that arrives with a clock several minutes fast can appear as not yet valid or already expired, and Kerberos outright rejects tickets with more than five minutes of difference from the server. Time isn’t a cosmetic detail, it’s a precondition for cryptography and distributed coordination to work.
How NTP works under the hood
NTP calculates the offset by comparing four timestamps in each exchange with a server. The client records T1 when sending the request; the server records T2 upon receiving it and T3 when responding; the client records T4 upon receiving the response.
sequenceDiagram
participant Client
participant Server
Client->>Server: request with timestamp T1
Server-->>Client: responds with T2 and T3
Note over Client,Server: Client records T4 upon receiving
Client->>Client: calculates offset with T1, T2, T3, T4
With those four timestamps, NTP obtains the offset and the round-trip delay using two formulas: offset = ((T2-T1)+(T3-T4))/2 and delay = (T4-T1)-(T3-T2). The offset tells the client how much to adjust its clock; the delay tells it how much confidence to give that sample, because a congested network inflates the delay and degrades precision.
The client doesn’t correct its clock all at once: it applies the adjustment gradually with a discipline algorithm (a mix of PLL and FLL) to avoid abrupt jumps that would break any time-sensitive process.
flowchart TD
A["Atomic clock / GPS (Stratum 0)"] --> B["Primary NTP server (Stratum 1)"]
B --> C["Secondary NTP server (Stratum 2)"]
C --> D["NTP client (Stratum 3)"]
C --> E["NTP client (Stratum 3)"]
When a client queries several sources at once, it needs to decide which ones to trust. NTP uses a variant of Marzullo’s algorithm to discard servers whose error interval doesn’t overlap with the majority’s, a process known as detecting a “falseticker”. That’s why the documentation recommends querying at least three or four sources: with just one there’s nothing to compare against.
Practical examples and how to get started
On Ubuntu and Debian, chrony is the recommended client over systemd-timesyncd when real precision is needed, because it adjusts the clock with frequency discipline instead of just occasional jumps.
sudo apt update
sudo apt install chrony
sudo systemctl enable --now chrony
This installs the package and starts the chrony service (on RHEL and Fedora the service is called chronyd). There’s no need to reboot the machine.
chronyc tracking
The output confirms whether the clock has already converged and at what reference stratum:
Reference ID : C0A80101 (2.debian.pool.ntp.org)
Stratum : 2
Ref time (UTC) : Mon Nov 02 14:21:08 2026
System time : 0.000012391 seconds slow of NTP time
Last offset : -0.000007823 seconds
RMS offset : 0.000045112 seconds
Frequency : 4.123 ppm slow
Skew : 0.089 ppm
Root delay : 0.023456789 seconds
Root dispersion : 0.004321098 seconds
Leap status : Normal
chronyc sources -v lists each server chrony is evaluating, along with its stratum and the symbol indicating whether it’s being used as the reference (*) or as a backup (+):
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 0.debian.pool.ntp.org 2 6 377 42 -74us[ -112us] +/- 23ms
^+ 1.debian.pool.ntp.org 2 6 377 45 +210us[ +198us] +/- 31ms
^- 2.debian.pool.ntp.org 3 6 377 40 -1.2ms[ -1.3ms] +/- 45ms
To add your own pool, edit /etc/chrony/chrony.conf and add a line like pool 2.debian.pool.ntp.org iburst, then restart the service with sudo systemctl restart chrony. Running chronyc sources -v again should show the new server in the list within a couple of minutes.
⚠️ Heads up: never leavechronyandsystemd-timesyncdactive at the same time: both try to adjust the same kernel clock, and the result is an unstable correction that oscillates between what each one believes is correct.
If the network goes down, chrony isn’t left blind: it saves the last known frequency correction in its driftfile and keeps applying it (a mode called holdover) until some server responds again.
Real-world use cases
In high-frequency financial markets, regulators require timestamps with a divergence of just microseconds from UTC, a level classic NTP doesn’t guarantee consistently. That pushes those firms toward PTP (IEEE 1588), a sibling protocol designed for local networks with dedicated timestamping hardware.
In a typical data center, NTP (via chrony) is enough to let logs from hundreds of machines be ordered and correlated during an incident investigation: without aligned clocks, reconstructing the exact sequence of events across different servers becomes practically impossible.
Distributed databases like Google’s Spanner go a step further: instead of relying on public NTP, they maintain their own time service backed by GPS and atomic clocks to offer consistency guarantees that a conventional NTP client couldn’t sustain.
At public scale, the NTP Pool Project distributes queries from millions of devices among servers donated by volunteers around the world, grouped into regional subdomains like 2.debian.pool.ntp.org.
Common mistakes and best practices
- A single NTP server: without at least three or four sources, the client can’t rule out a server with the wrong time (a falseticker).
- Blocked UDP port 123: a corporate firewall that closes it leaves the clock drifting with no visible error until something involving TLS or Kerberos fails.
- Two time daemons at once: having chrony and systemd-timesyncd active simultaneously makes them compete to adjust the same clock.
- Trusting a VM’s clock without its own NTP: a live migration or a hypervisor pause can jump the guest’s clock by several seconds at once.
- Ignoring leap seconds: an unhandled one-second jump can break software that assumes time never goes backward.
Comparison: NTP versus other ways to synchronize the clock
Before choosing a tool, it’s useful to compare how precise the clock actually needs to be. The NTP protocol covers the vast majority of cases, but it isn’t the only option.
| Option | Typical precision | When to use it | Limitation |
|---|---|---|---|
| NTP with chrony | Milliseconds on the internet, sub-millisecond on LAN | Servers, laptops, and containers without extreme requirements | Doesn’t authenticate the time source unless NTS is configured |
| systemd-timesyncd (SNTP) | Lower, without fine frequency discipline | Desktops with no need for precision | Can’t act as a server for other clients |
| PTP (IEEE 1588) | Microseconds or better | High-frequency trading, telecom, laboratories | Requires switches and network cards with hardware support |
| GPS or atomic clock (stratum 0) | Primary reference | Feeding your own stratum 1 servers | Cost of antenna, receiver, and a clear view of the sky |
Going deeper: security and advanced precision
The classic version of NTP doesn’t authenticate its responses: anyone who can intercept the UDP traffic can spoof the time a client receives. RFC 8915 defines NTS (Network Time Security), which uses TLS to negotiate keys and then protects each time packet with an authentication code, without carrying the overhead of encrypting each full message.
💭 Key point: public services like Google Public NTP don’t apply the leap second all at once: they spread it out (leap smear) over several hours so clients never see the clock jump backward.
To choose among sources, chrony and ntpd combine Marzullo’s intersection algorithm with a clustering algorithm that weighs each sample by its accumulated dispersion, so a server with low latency but poor historical precision can weigh less than one that’s slower but stable.
Your next step: run chronyc tracking on your own Linux machine and compare the Stratum field with that of another device on your network to confirm both converge to the same hierarchy.
Frequently Asked Questions
What network port does NTP use?
NTP exchanges its messages over UDP port 123, both for clients requesting the time and for servers responding with it. It uses UDP because it prioritizes speed and latency consistency over delivery guarantees.
What’s the difference between a stratum 1 and a stratum 2 server?
A stratum 1 server is connected directly to a reference clock like GPS or an atomic clock, without going through the network to get the time. A stratum 2 server gets the time from one or more stratum 1 servers over the network, so it accumulates some of the delay and error from that connection.
chrony or systemd-timesyncd: which should I use?
systemd-timesyncd is enough for a desktop that only needs an approximate time. chrony is the better choice for servers, laptops that suspend frequently, and any case where precision and quickly resyncing after an outage really matter.
Is the NTP protocol secure?
Not by default: an attacker on the same network can spoof the responses because classic NTP doesn’t authenticate the origin of the packets. NTS, defined in RFC 8915, adds that authentication using TLS to negotiate the keys before synchronization begins.
Can I run an NTP server without an internet connection?
Yes. A USB-connected GPS receiver or a low-cost atomic clock can act as a local stratum 0, and chrony exposes it as a reference for the rest of the internal network without depending on any external server.
How do I know if my Linux system is using chrony or systemd-timesyncd?
systemctl status chrony and systemctl status systemd-timesyncd show which of the two is active. Only one should be: having them run together makes them compete to adjust the same clock.
References
- RFC 5905: the official specification for NTPv4, the protocol described in this article.
- RFC 8915: defines NTS (Network Time Security), the extension that authenticates NTP messages.
- chrony: the official site for the NTP client and server used in this article’s examples.
- NTP Pool Project: a volunteer network of public NTP servers like those under the pool.ntp.org domain.
- Google Public NTP: documentation for Google’s public time service and its handling of the leap second.
- Wikipedia: Network Time Protocol: a historical and technical overview of the protocol.
📱 Like this content? Follow @programacion on Telegram for daily tech content in Spanish: quick summaries, fresh content every day.
Featured image: Foto de Donald Wu en Unsplash
Did it work for you? Got a different error? Say so below: questions get answered and help the next reader.
Leave a comment
0 Comments