Configure and Verify systemd-timesyncd Clock Sync
A drifting clock fails TLS handshakes and scrambles log ordering, and systemd-timesyncd is the quiet daemon meant to stop that. By the end of this guide it will have a clear NTP server policy, and you will be able to prove whether the local clock is actually synchronised. The examples use the systemd 255 manpages installed with Ubuntu package version 255.4-1ubuntu8.17. Allow about 10 minutes, including time for a status check after a configuration change.
The route
Jump straight to the step you need, or tick off Done means at the end.
1. Check the current state
Start with read-only checks. You need a shell account that can run systemctl and timedatectl; changing the service or its configuration later needs sudo. Do not treat a running service as proof that the clock is accurate.
$ systemctl is-enabled systemd-timesyncd.service
enabled
$ systemctl is-active systemd-timesyncd.service
active
$ timedatectl status
Local time: ...
Universal time: ...
System clock synchronized: yes
NTP service: active
The exact dates and spacing vary. What you're checking is the enabled and active states, followed by System clock synchronized: yes and an active NTP service. If the unit is inactive, continue to the next step before touching its servers.
2. Inspect the detailed synchronisation result
timedatectl timesync-status gives you the server currently selected, the poll interval and the measured offset. It is the quickest way to tell a working client apart from a service that merely started:
$ timedatectl timesync-status
Server: 203.0.113.20 (time.example.net)
Poll interval: 34min 8s (min: 32s; max 34min 8s)
Leap: normal
Version: 4
Stratum: 2
Root distance: 18.325ms (max: 5s)
Offset: +133us
Delay: 466us
Packet count: 666
- Address and measurements will differ on your host. A normal leap status, a server name or address, and a non-zero packet count are useful evidence.
- Root distance must stay below its configured maximum. If the command reports no usable server, check networking and name resolution before tuning intervals.
For a machine-readable view, run timedatectl show-timesync. It exposes fields such as ServerName, RootDistanceMaxUSec and PollIntervalUSec, which is also handy when a monitoring script should not be parsing the human-readable table.
3. Choose the server policy
Timesyncd implements SNTP, not a full NTP daemon. It can step the clock for a large offset or gradually adjust a smaller one, but it is not the right service if you need full NTP features. On a normal workstation or small server, its simple client model is usually enough.
- Servers can come from three places: the global
timesyncd.confsettings, static per-link settings in.networkfiles, and DHCP information. - Per-link servers and an explicit
NTP=setting win overFallbackNTP=. The fallback list is used only when no other server information is known; do not add a fallback just to override a server supplied by DHCP.
Inspect the effective configuration before editing anything:
$ systemd-analyze cat-config systemd/timesyncd.conf
$ timedatectl show-timesync
SystemNTPServers=...
FallbackNTPServers=...
ServerName=...
RootDistanceMaxUSec=5s
The first command shows the main file and drop-ins in their load order. The second shows what the running service currently knows. A configured server list is not the same thing as a successful response.
4. Add a local drop-in
Use a drop-in under /etc/systemd/timesyncd.conf.d/ for local policy rather than editing a vendor file. Drop-in filenames sort lexicographically, and a later value wins for options that accept only one; a two-digit prefix keeps the intended ordering visible.
This example sets two organisation-approved servers. Replace the hostnames with names you have actually verified for your network. It is an elevated, persistent change, so check the names first and keep the old configuration around for recovery.
$ sudo install -d -m 0755 /etc/systemd/timesyncd.conf.d
$ sudo tee /etc/systemd/timesyncd.conf.d/20-local-ntp.conf >/dev/null <<'EOF'
[Time]
NTP=time.example.net time-backup.example.net
EOF
Restart the service so it rereads the configuration:
$ sudo systemctl restart systemd-timesyncd.service
$ systemctl is-active systemd-timesyncd.service
active
$ timedatectl timesync-status
A restart can briefly leave the clock without a current network sample; it does not deliberately wait for accurate synchronisation before unrelated units start. If a unit must wait for an accurate reference clock, look at systemd-time-wait-sync.service rather than adding arbitrary sleeps.
5. Verify the new server
Give the client time to make a request, then check the selected server and its measurements. The minimum poll interval is 32 seconds by default, and the client may take longer to pick a responsive server.
$ timedatectl timesync-status
Server: 192.0.2.20 (time.example.net)
Leap: normal
Stratum: 2
Root distance: 12.4ms (max: 5s)
Offset: -41us
Packet count: 3
$ timedatectl status | grep -E 'System clock synchronized|NTP service'
System clock synchronized: yes
NTP service: active
If ServerName stays empty or the packet count does not increase, check the journal:
$ journalctl -u systemd-timesyncd.service -b --no-pager
$ resolvectl query time.example.net
$ getent ahosts time.example.net
Look for name resolution failures, unreachable addresses, blocked UDP traffic or a server rejected because its root distance is too large. Test the network path and the server policy before lowering RootDistanceMaxSec=: accepting a poor time source can make the result less trustworthy, not more.
6. Understand the clock files
After a successful synchronisation, timesyncd updates the modification time of /var/lib/systemd/timesync/clock. At boot it can use that timestamp to advance the realtime clock when the host lacks a battery-backed RTC. If that file does not exist, systemd 255 can use /usr/lib/clock-epoch when available; that is a rough monotonic starting point, not proof the clock is currently synchronised.
The file /run/systemd/timesync/synchronized is touched after successful synchronisation and helps systemd-time-wait-sync and other applications detect that event. These paths are implementation state: do not hand-edit their timestamps to make a monitoring check pass.
SaveIntervalSec= controls how often the current time is saved when there has been no recent NTP synchronisation; its default is 60 seconds in this installed version. Changing it does not make network synchronisation more frequent.
7. Tune only a measured problem
The defaults are a sensible starting point: a 5 second maximum root distance, a 32 second minimum poll interval, a 2048 second maximum poll interval, a 30 second retry delay and a 60 second save interval. The minimum poll interval cannot be less than 16 seconds, and the maximum must be greater than the minimum.
For example, if an offline appliance needs a longer persistence interval, add only the one setting you have a reason to change:
[Time]
SaveIntervalSec=5min
Do not copy a collection of interval values from another host without measuring its network and clock behaviour. Very short polling increases traffic and creates avoidable load; too large a root-distance limit can accept a time source that is too far from its reference clock.
8. Roll back cleanly
If the new policy causes failures, remove only the drop-in you created and restart the service. This is a persistent configuration change, but the rollback is simple and does not touch the vendor configuration.
$ sudo rm /etc/systemd/timesyncd.conf.d/20-local-ntp.conf
$ sudo systemctl restart systemd-timesyncd.service
$ systemd-analyze cat-config systemd/timesyncd.conf
$ timedatectl timesync-status
Recovery
Confirm the filename with ls -l /etc/systemd/timesyncd.conf.d/ before removing anything. Never wipe a directory wholesale when several administrators or packages may have placed drop-ins there. If another NTP implementation is installed, check its unit conflicts before enabling it: two services should not be fighting over the same clock.
Done means
- Version and config known. The installed package version and the effective configuration are known.
- Server confirmed. The selected server appears in
timedatectl timesync-status. - Clock synchronised. The clock reports synchronised and the packet count advances.
- Root distance in range. The root distance is below the configured limit.
- Local policy isolated. Any local policy lives in a named drop-in under
/etc/systemd/timesyncd.conf.d/. - Rollback tested. You can remove that drop-in and restart the service to undo the change.