Keeping accurate time isn’t just nice—it’s essential. Log correlation, TLS certificate validation, Kerberos and OAuth tokens, cron/systemd timers, database replication, and distributed systems all assume your server’s clock is within a few seconds of reality. Here’s a practical, copy‑paste friendly guide to check whether your Linux server’s time is correct and fix it if it isn’t.
TL;DR (Quick Checklist)
- Confirm the clock & timezone
|
1 2 3 4 |
date -u date timedatectl status |
- Verify NTP sync is ON and healthy
|
1 2 3 |
timedatectl timesync-status 2>/dev/null || true chronyc tracking 2>/dev/null || ntpq -p 2>/dev/null |
- If skewed, do a safe step (schedule off-hours if drift is large)
|
1 2 3 |
sudo chronyc -a makestep || true sudo timedatectl set-ntp true |
- Persist RTC (hardware clock) after fix
|
1 2 |
sudo hwclock --systohc |
- Allow NTP (UDP/123) and ensure reputable upstream servers are configured.
Step 1 — Check What Time Your Server Thinks It Is
Run these and look for surprises:
|
1 2 3 4 5 6 7 |
# Human view in local zone and in UTC date date -u # systemd summary (if present) timedatectl status |
You want:
- Local time and UTC to be the expected values for your region.
System clock synchronized: yes(or equivalent) and an active NTP service.- A sensible timezone (often UTC on servers).
Confirm the Timezone
|
1 2 3 |
ls -l /etc/localtime cat /etc/timezone 2>/dev/null || true |
If it’s not what you want:
|
1 2 3 4 5 |
# Example: set to UTC sudo timedatectl set-timezone UTC # Example: set to America/New_York sudo timedatectl set-timezone America/New_York |
Tip: For most servers, UTC is recommended. If you must run in a local timezone (e.g., appliances with local-only logs, or legal reporting that mandates local time), document it and standardize across hosts.
Step 2 — Verify NTP Synchronization
Accurate servers don’t set time once; they continuously discipline it via NTP.
If you use chrony (common on RHEL, Rocky, Alma, Fedora, Amazon Linux 2023+ and modern Ubuntu):
|
1 2 3 4 5 6 7 |
# Overall status chronyc tracking # Peers and offsets chronyc sources -v # Test reachability chronyc sourcestats -v |
Healthy signs: small “Last offset” (microseconds to low milliseconds), positive reachability (octal 377 best), and stable frequency.
If you use systemd-timesyncd (lightweight, default on many Debian/Ubuntu minimal installs):
|
1 2 3 4 5 6 |
# Enable and view status sudo timedatectl set-ntp true systemctl status systemd-timesyncd # Check sync details (newer systemd) timedatectl timesync-status |
If you use the legacy ntpd (less common on new installs):
|
1 2 3 |
ntpq -p ntpstat || true |
Rule of thumb: Prefer chrony for servers. It handles network jitter, virtualization, and suspend/resume scenarios more gracefully than classic ntpd.
Step 3 — Compare Against an External Reference (Optional Sanity Check)
Even when NTP reports healthy, you can sanity‑check offset:
|
1 2 3 4 5 |
# Requires chrony client tools date -u; chronyc tracking # Or query a known-good source (read-only) ntpdate -q 0.pool.ntp.org 2>/dev/null || true |
You’re looking for offset within a few milliseconds to tens of milliseconds for well-connected servers. Bigger is okay temporarily during convergence but should settle quickly.
Step 4 — Fix Skew Safely
Assess drift size:
- Small drift (<1s): Let NTP converge naturally.
- Medium (1s–30s): Use a controlled step with chrony.
- Large (>30s or minutes): Schedule a maintenance window—stepping time can confuse apps, cron, and clustered systems.
With chrony (recommended)
|
1 2 3 4 5 6 |
# Immediately step system clock if the offset is large sudo chronyc -a makestep # Ensure service is enabled and using good sources sudo systemctl enable --now chronyd sudo sed -n '1,120p' /etc/chrony.conf |
Edit /etc/chrony.conf to use reputable sources (pool or vendor/service NTP). Then:
|
1 2 3 |
sudo systemctl restart chronyd chronyc tracking; chronyc sources -v |
With systemd-timesyncd
|
1 2 3 4 5 |
sudo timedatectl set-ntp true sudo systemctl restart systemd-timesyncd # On newer systemd, you can trigger a resync sudo systemctl restart systemd-timesyncd && sleep 2 && timedatectl timesync-status |
With legacy ntpd
|
1 2 3 4 5 |
# Force a one-time step if far off sudo service ntp stop || sudo systemctl stop ntp sudo ntpd -gq sudo service ntp start || sudo systemctl start ntp |
Persist to Hardware Clock (RTC)
After you’re happy with the system time, write it to the RTC so reboots start close to correct:
|
1 2 |
sudo hwclock --systohc |
Step 5 — Common Pitfalls & How to Avoid Them
- Firewall blocks UDP/123: Allow outbound NTP to your sources (and inbound if you run an internal NTP server).
- Multiple time daemons fighting: Don’t run chronyd, ntpd, and timesyncd simultaneously. Pick one (prefer chrony) and disable the others.
- Virtualized guests: Avoid host‑guest double discipline. Let either the hypervisor provide time (via paravirtual clock) or the guest use NTP—document your standard. For KVM, ensure
kvm-clock/tscstability and NTP inside the guest. - Containers: Containers inherit the host clock. Fix the host; don’t try to run NTP inside most containers.
- Bad/ flaky upstreams: Use multiple, diverse NTP sources. Consider your cloud provider’s NTP (e.g., AWS Time Sync, Azure Time) or regional pools.
- RTC localtime vs UTC: Servers should keep RTC in UTC. Check:
123timedatectl status | grep RTCsudo timedatectl set-local-rtc 0 - Daylight Saving Time surprises: DST doesn’t change UTC, but localtime shifts by ±1h. Prefer UTC on servers to avoid timer/cron confusion.
Distro‑Specific Notes
RHEL / Rocky / Alma / CentOS 7+
- Default: chronyd.
- Key commands:
1234sudo systemctl status chronydsudo systemctl enable --now chronydchronyc tracking; chronyc sources -v
Ubuntu 18.04+ / Debian 10+
- Default varies by image: systemd-timesyncd or chrony.
- Switch to chrony (recommended):
1234sudo apt-get update && sudo apt-get install -y chronysudo systemctl enable --now chronychronyc tracking
Amazon Linux 2 / 2023
- Preferred: chrony using AWS Time Sync (169.254.169.123).
1234sudo systemctl enable --now chronydsudo sed -n '1,120p' /etc/chrony.conf | sed -n '1,30p'chronyc sources -v
SUSE (SLES/OpenSUSE)
- chrony is available and recommended. Older setups might use ntpd.
Production Hardening & Monitoring
- Pin your upstreams: Use cloud/vendor NTP where available; otherwise use the NTP pool with multiple servers.
- Alerting: Watch for: service down,
System clock synchronized: no, large offset, or peer reachability drop. - Log evidence:
123journalctl -u chronyd --since "-1h"journalctl -u systemd-timesyncd --since "-1h" - Document standard: Timezone (usually UTC), chosen daemon (chrony), upstreams, and how to recover from large drift.
Conclusion
Time drift is silent technical debt—it accumulates until it breaks something at the worst moment. With a few quick checks (date, timedatectl, chronyc) and a standard approach (prefer chrony, keep RTC in UTC, monitor offsets), you can keep your servers within milliseconds of the real world and your operations predictable.




