{"id":1160,"date":"2026-09-17T22:34:58","date_gmt":"2026-09-17T22:34:58","guid":{"rendered":"https:\/\/virtualserversvps.com\/blog\/?p=1160"},"modified":"2026-09-17T22:34:58","modified_gmt":"2026-09-17T22:34:58","slug":"chrony-time-sync-vps-clock-drift","status":"publish","type":"post","link":"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/","title":{"rendered":"Time Synchronization on a VPS with chrony: Fixing Clock Drift Before It Breaks TLS and Databases"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Clock drift is one of the few server problems that produces symptoms nowhere near its cause. A VM whose clock has drifted a few seconds can reject TLS connections, invalidate authentication tokens, corrupt database ordering assumptions, and break distributed locks \u2014 while the CPU, memory, and disk graphs all look perfectly healthy. Virtual machines drift faster than physical hardware because the guest clock is derived from the hypervisor&#8217;s virtual timer, which is affected by scheduling and CPU migration. Here is how to detect drift and fix it properly with chrony.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Confirm You Have a Drift Problem<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Start by measuring the offset against a known-good source:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Current tracking status \u2014 offset, frequency, last sync&#010;chronyc tracking&#010;&#010;# NTP synchronisation state of the kernel clock&#010;timedatectl status&#010;&#010;# Sources and their measured offsets&#010;chronyc sources -v<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In <code>chronyc tracking<\/code>, the line to watch is <strong>System time<\/strong> \u2014 the current offset from real time. Sub-millisecond is healthy. Values measured in seconds mean the clock has not been disciplined properly, or <code>chronyd<\/code> is not running at all. The <strong>Frequency<\/strong> value tells you how fast the clock is drifting in parts per million; a large frequency means <code>chronyd<\/code> is working hard to correct a badly skewed oscillator, which is normal on VMs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why VMs Drift More Than Bare Metal<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Virtual timers<\/strong> \u2014 guest time is derived from a virtualised clock source, which is subject to host scheduling jitter.<\/li><li><strong>vCPU migration<\/strong> \u2014 when a guest thread moves between physical cores, the TSC on the destination core may not be perfectly aligned.<\/li><li><strong>Save\/restore and migration<\/strong> \u2014 suspended or live-migrated VMs resume with a clock that is behind by the duration of the pause.<\/li><li><strong>Clock source choice<\/strong> \u2014 <code>kvm-clock<\/code> is typically the most accurate source in a KVM guest; falling back to <code>tsc<\/code> or <code>hpet<\/code> can be measurably worse.<\/li><li><strong>Steal time<\/strong> \u2014 if the host is oversubscribed, the guest&#8217;s timer interrupts arrive late, and the clock accumulates error.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You can check the clock source and confirm the hypervisor exposes a paravirtualised clock:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat \/sys\/devices\/system\/clocksource\/clocksource0\/current_clocksource&#010;cat \/sys\/devices\/system\/clocksource\/clocksource0\/available_clocksource&#010;dmesg | grep -i -E 'kvm-clock|clocksource'<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Install and Configure chrony<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">chrony is the default on RHEL-family and modern Debian\/Ubuntu images, and it outperforms the older <code>ntpd<\/code> in virtualised environments because it converges faster after a VM resumes from a pause. A reasonable base configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \/etc\/chrony\/chrony.conf  (Debian\/Ubuntu)&#010;pool 2.debian.pool.ntp.org iburst maxsources 4&#010;&#010;# Step the clock if the offset is large \u2014 useful after VM restore&#010;makestep 1.0 3&#010;&#010;# Record drift so it converges faster on restart&#010;driftfile \/var\/lib\/chrony\/chrony.drift&#010;&#010;# Do not serve time to the network unless required&#010;port 0&#010;&#010;# Log statistics for post-incident review&#010;logdir \/var\/log\/chrony&#010;log measurements statistics tracking<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>makestep 1.0 3<\/code> directive is important on VMs. It instructs chrony to step the clock \u2014 rather than slowly slew it \u2014 if the offset exceeds one second during the first three updates after startup. This is exactly the case that occurs after a VM snapshot resume, where the clock can be minutes behind.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Apply and verify:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl restart chrony&#010;chronyc tracking&#010;chronyc sources -v&#010;timedatectl status<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">What Breaks When the Clock Is Wrong<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>System<\/th><th>Symptom of drift<\/th><th>Tolerance<\/th><\/tr><\/thead><tbody><tr><td>TLS certificates<\/td><td>&quot;Certificate not yet valid&quot; \/ expired errors<\/td><td>Seconds to minutes<\/td><\/tr><tr><td>JWT \/ OAuth tokens<\/td><td>Token rejected as expired or not-yet-valid<\/td><td>Typically 30\u2013300&nbsp;s<\/td><\/tr><tr><td>Kerberos<\/td><td>Authentication failures (replay protection)<\/td><td>~5 minutes<\/td><\/tr><tr><td>Database replication<\/td><td>Stale reads, inconsistent timestamps, GTID issues<\/td><td>Milliseconds to seconds<\/td><\/tr><tr><td>Distributed locks<\/td><td>Split-brain, duplicate job execution<\/td><td>Milliseconds<\/td><\/tr><tr><td>Log correlation<\/td><td>Events appear out of order across hosts<\/td><td>Seconds<\/td><\/tr><tr><td>Cron<\/td><td>Jobs skipped or run twice<\/td><td>Seconds<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The database row deserves emphasis. Multi-node replication, time-based partitioning, and audit logging all assume clocks are monotonic and comparable. In a multi-server deployment, even a two-second skew between primary and replica can produce confusing replication errors that look like application bugs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Monitoring Clock Offset<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Treat clock offset as a monitored metric, not a one-time fix. Export it to your monitoring system so a drift that exceeds threshold pages you before applications fail:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Raw offset in seconds, suitable for a textfile collector&#010;chronyc tracking | awk '\/System time\/ {print $4}'&#010;&#010;# One-line health check for cron&#010;chronyc tracking | awk '\/System time\/ {v=$4; if (v&lt;0) v=-v; if (v&gt;0.5) print \"DRIFT ALERT: \" v \"s\"}'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A useful threshold is 100&nbsp;ms for alerting and 1&nbsp;s for paging. If you are running databases or authentication services on the same host, tighten it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Post-Restore and Post-Migration Handling<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Every time a VM is restored from a snapshot or live-migrated, assume its clock is wrong. If you run automated snapshot-based backups, add a clock check to the restore verification step. A server that comes back with a five-minute-old clock will silently fail TLS handshakes until the offset is corrected \u2014 and if <code>makestep<\/code> is not configured, chrony will slew the correction over hours instead of fixing it immediately.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On a full-virtualisation instance with its own kernel, you control the clock source, the chrony configuration, and the step policy directly. Rental plans at <a href=\"https:\/\/virtualserversvps.com\/\">virtualserversvps.com<\/a> run full VMs rather than shared containers, so kernel-level time settings are yours to tune rather than fixed by the host&#8217;s container policy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Checklist<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Verify <code>chronyd<\/code> is running and <code>timedatectl<\/code> reports active synchronisation.<\/li><li>Confirm the clock source is <code>kvm-clock<\/code> (or <code>xen<\/code>) rather than a slow fallback.<\/li><li>Set <code>makestep 1.0 3<\/code> so post-restore clock jumps are corrected instantly.<\/li><li>Configure a drift file so convergence is fast after reboot.<\/li><li>Monitor offset continuously and alert at 100&nbsp;ms.<\/li><li>Re-check the clock after every snapshot restore and live migration.<\/li><li>Align all hosts in a cluster to the same upstream sources, so skew between them stays bounded.<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Clock drift is one of the few server problems that produces symptoms nowhere near its cause. A VM whose clock has drifted a few seconds can reject TLS connections, invalidate&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":1,"footnotes":""},"categories":[4],"tags":[],"class_list":["post-1160","post","type-post","status-publish","format-standard","hentry","category-security-compliance"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Time Synchronization on a VPS with chrony: Fixing Clock Drift Before It Breaks TLS and Databases - Virtual Servers VPS Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Time Synchronization on a VPS with chrony: Fixing Clock Drift Before It Breaks TLS and Databases\" \/>\n<meta property=\"og:description\" content=\"Time Synchronization on a VPS with chrony: Fixing Clock Drift Before It Breaks TLS and Databases\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual Servers VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-17T22:34:58+00:00\" \/>\n<meta name=\"author\" content=\"Virtual-Servers-Vps-Editor\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Virtual-Servers-Vps-Editor\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/\",\"name\":\"Time Synchronization on a VPS with chrony: Fixing Clock Drift Before It Breaks TLS and Databases - Virtual Servers VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\"},\"datePublished\":\"2026-09-17T22:34:58+00:00\",\"author\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\"},\"breadcrumb\":{\"@id\":\"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtualserversvps.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Time Synchronization on a VPS with chrony: Fixing Clock Drift Before It Breaks TLS and Databases\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#website\",\"url\":\"https:\/\/virtualserversvps.com\/blog\/\",\"name\":\"Virtual Servers VPS Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0\",\"name\":\"Virtual-Servers-Vps-Editor\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g\",\"caption\":\"Virtual-Servers-Vps-Editor\"},\"sameAs\":[\"https:\/\/virtualserversvps.com\/blog\"],\"url\":\"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Time Synchronization on a VPS with chrony: Fixing Clock Drift Before It Breaks TLS and Databases - Virtual Servers VPS Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/","og_locale":"en_US","og_type":"article","og_title":"Time Synchronization on a VPS with chrony: Fixing Clock Drift Before It Breaks TLS and Databases","og_description":"Time Synchronization on a VPS with chrony: Fixing Clock Drift Before It Breaks TLS and Databases","og_url":"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/","og_site_name":"Virtual Servers VPS Blog","article_published_time":"2026-09-17T22:34:58+00:00","author":"Virtual-Servers-Vps-Editor","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Virtual-Servers-Vps-Editor","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/","url":"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/","name":"Time Synchronization on a VPS with chrony: Fixing Clock Drift Before It Breaks TLS and Databases - Virtual Servers VPS Blog","isPartOf":{"@id":"https:\/\/virtualserversvps.com\/blog\/#website"},"datePublished":"2026-09-17T22:34:58+00:00","author":{"@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0"},"breadcrumb":{"@id":"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/virtualserversvps.com\/blog\/chrony-time-sync-vps-clock-drift\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtualserversvps.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Time Synchronization on a VPS with chrony: Fixing Clock Drift Before It Breaks TLS and Databases"}]},{"@type":"WebSite","@id":"https:\/\/virtualserversvps.com\/blog\/#website","url":"https:\/\/virtualserversvps.com\/blog\/","name":"Virtual Servers VPS Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/virtualserversvps.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/82a299a8284a66ff49f97c74684724a0","name":"Virtual-Servers-Vps-Editor","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/virtualserversvps.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d820b15f1cd028e97610d9adf536df7be5cb6423869967037d468d5355fa003f?s=96&d=mm&r=g","caption":"Virtual-Servers-Vps-Editor"},"sameAs":["https:\/\/virtualserversvps.com\/blog"],"url":"https:\/\/virtualserversvps.com\/blog\/author\/virtualserversvps\/"}]}},"_links":{"self":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1160","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/comments?post=1160"}],"version-history":[{"count":1,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1160\/revisions"}],"predecessor-version":[{"id":1164,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/posts\/1160\/revisions\/1164"}],"wp:attachment":[{"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/media?parent=1160"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/categories?post=1160"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtualserversvps.com\/blog\/wp-json\/wp\/v2\/tags?post=1160"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}