<figure class="wp-block-image aligncenter"><img src="https://flowgenius.in/wp-content/uploads/2026/01/n8n-clock-sync-time-drift-issues.png" alt="Step by Step Guide to solve n8n clock sync time drift issues" /> <figcaption style="text-align: center;">Step by Step Guide to solve n8n clock sync time drift issues</p>
<hr />
</figcaption></figure>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Who this is for: </strong>Ops engineers, DevOps teams, and n8n administrators who run scheduled workflows or webhook integrations in production. <strong>We cover this in detail in the </strong><a href="https://flowgenius.in/n8n-architectural-failure-modes/">n8n Architectural Failure Modes Guide.</a></p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">Quick Diagnosis</h2>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Problem:</strong> n8n’s scheduled workflows run early, late, or skip entirely because the server’s clock has drifted away from real time.</p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Quick fix:</strong></p>
<ol style="margin-bottom: 1.8em; line-height: 1.9;">
<li>Verify the host’s time (must be UTC and within 2 seconds).</li>
<li>Restart the host’s NTP service.</li>
<li>Restart the n8n container.</li>
</ol>
<p style="margin-bottom: 2em; line-height: 1.9;">It often appears after a VM pause or a brief network hiccup that stalls NTP.<br />
If the drift reappears, follow the detailed steps below.</p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">1. Why Clock Sync Matters for n8n?</h2>
<p><strong>If you encounter any </strong><a href="/n8n-failures-under-network-partitions">n8n failures under network partitions </a><strong>resolve them before continuing with the setup.<br />
</strong><em>Accurate time underpins all time‑sensitive features in n8n.</em></p>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">n8n Feature</th>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">Dependency on Accurate Time</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Cron / Schedule Trigger</td>
<td style="padding: 13px; border: 1px solid #ddd;">Executes when <code>now >= nextTrigger</code>.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Webhooks with <code>expiresAt</code></td>
<td style="padding: 13px; border: 1px solid #ddd;">Validates request timestamps.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Credential OAuth token refresh</td>
<td style="padding: 13px; border: 1px solid #ddd;">Calculates <code>expires_in</code>.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Execution logs & audit</td>
<td style="padding: 13px; border: 1px solid #ddd;">Stores ISO‑8601 timestamps.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">External APIs (e.g., Stripe, PayPal)</td>
<td style="padding: 13px; border: 1px solid #ddd;">Require request timestamps within ±5 s.</td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 2em; line-height: 1.9;">When the OS clock drifts, each component inherits the error, leading to missed runs, duplicate executions, or authentication failures.</p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">2. Typical Symptoms of n8n Time‑Drift</h2>
<p>If you encounter any <a href="/n8n-behavior-during-cloud-outages">n8n behavior during cloud outages </a>resolve them before continuing with the setup.</p>
<p style="margin-bottom: 2em; line-height: 1.9;"><em>Spot the warning signs before they break your pipelines.</em></p>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">Symptom</th>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">UI / Log Appearance</th>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">Likely Impact</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Scheduled workflow fires early</td>
<td style="padding: 13px; border: 1px solid #ddd;">Timestamp earlier than the cron expression (e.g., <code>0 12 * * *</code> runs at 11:58)</td>
<td style="padding: 13px; border: 1px solid #ddd;">Duplicate data, race conditions</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Scheduled workflow fires late / skips</td>
<td style="padding: 13px; border: 1px solid #ddd;">No execution entry for the expected run; next run appears minutes/hours later</td>
<td style="padding: 13px; border: 1px solid #ddd;">Missed deadlines, SLA breach</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Webhook “Signature expired”</td>
<td style="padding: 13px; border: 1px solid #ddd;"><code>Error: Request timestamp is outside the allowed window</code></td>
<td style="padding: 13px; border: 1px solid #ddd;">Incoming integrations break</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">OAuth token refresh loop</td>
<td style="padding: 13px; border: 1px solid #ddd;">Repeated <code>Token refresh failed</code> errors despite valid credentials</td>
<td style="padding: 13px; border: 1px solid #ddd;">API calls fail, downstream steps error</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Inconsistent audit timestamps</td>
<td style="padding: 13px; border: 1px solid #ddd;"><code>CreatedAt</code> and <code>FinishedAt</code> fields out of order</td>
<td style="padding: 13px; border: 1px solid #ddd;">Debugging becomes impossible</td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 2em; line-height: 1.9;">If you see any of these, start with the Quick Diagnosis checklist.</p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">3. Root Causes of Clock Drift in n8n Deployments</h2>
<p>If you encounter any <a href="/n8n-retry-logic-financial-workflows">n8n retry logic financial workflows </a>resolve them before continuing with the setup.</p>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">Source</th>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">Description</th>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">Production‑grade Warning</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Host OS without NTP</td>
<td style="padding: 13px; border: 1px solid #ddd;">No daemon to keep system clock aligned</td>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Critical</strong> – drift can accumulate 1 s/min on idle VMs</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Docker containers using host time</td>
<td style="padding: 13px; border: 1px solid #ddd;">Containers inherit host clock; if host drifts, all containers drift</td>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>High</strong> – isolated containers do not self‑correct</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">CPU throttling / cgroup limits</td>
<td style="padding: 13px; border: 1px solid #ddd;">Heavy CPU limits can cause the kernel clock to lag</td>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Medium</strong> – only in highly constrained environments</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Timezone mis‑configuration</td>
<td style="padding: 13px; border: 1px solid #ddd;">n8n runs in UTC, but host set to local TZ, causing conversion errors</td>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Low</strong> – usually harmless but can confuse logs</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Database server time mismatch</td>
<td style="padding: 13px; border: 1px solid #ddd;">DB clock differs from n8n host</td>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>High</strong> – execution timestamps stored in DB become inconsistent</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Virtualized cloud instances</td>
<td style="padding: 13px; border: 1px solid #ddd;">Some cloud VMs have coarse time sync</td>
<td style="padding: 13px; border: 1px solid #ddd;"><strong>Medium</strong> – enable <code>chrony</code> or <code>ntp</code> in the VM</td>
</tr>
</tbody>
</table>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">4. Step‑by‑Step Diagnosis & Fixes</h2>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.1 Verify Host Time & NTP Status</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">Run these commands on the host to see the current UTC time and NTP health:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;"># Show current UTC time
date -u</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;"># Check chrony synchronization status
chronyc tracking</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;"># If you use ntp instead of chrony
ntpq -p</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">On production servers, enforce <code>chrony</code> with <code>maxdelay 0.5</code> to guarantee sub‑second accuracy.</p>
<p style="margin-bottom: 2em; line-height: 1.9;">If the offset is > 2 seconds, restart the NTP daemon:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;"># For chrony
sudo systemctl restart chronyd</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;"># For ntp
sudo systemctl restart ntp</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.2 Confirm Docker Container Time</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">Check that the n8n container sees the same UTC time as the host:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;">docker exec -it <n8n_container> date -u</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">If the container’s time differs, the host is still off or the container isn’t sharing the host’s timezone files. Without those mounts the container falls back to its own clock, causing the mismatch.</p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Fix the mount configuration (docker‑compose excerpt):</strong></p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;">services:
n8n:
image: n8nio/n8n
volumes:
- /etc/localtime:/etc/localtime:ro</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;">services:
n8n:
volumes:
- /etc/timezone:/etc/timezone:ro</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">These mounts ensure the container uses the host’s clock and timezone.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.3 Check Database Server Clock</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">Run the appropriate query on your DB server:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;">-- Postgres
SELECT now() AT TIME ZONE 'UTC';</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;">-- MySQL
SELECT UTC_TIMESTAMP();</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">If the DB time diverges, sync the DB host with the same NTP method you used for the n8n host.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.4 Align n8n’s Internal Timezone</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">Set the environment variable to force UTC throughout n8n:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;"># In .env or docker‑compose
N8N_TIMEZONE=UTC</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">This eliminates any surprises caused by local‑timezone conversions.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">4.5 Re‑deploy n8n After Sync</h3>
<p style="margin-bottom: 2em; line-height: 1.9;">Pull the latest image and recreate the container so it reads the corrected clock:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;">docker compose pull n8n</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;">docker compose up -d --force-recreate n8n</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">A clean redeploy is usually faster than hunting for hidden timezone caches. A fresh start guarantees the updated system time is applied.</p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">5. Preventive Monitoring & Alerts</h2>
<p style="margin-bottom: 2em; line-height: 1.9;"><em>Proactively catch drift before it hurts your workflows.</em></p>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">Tool</th>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">Metric / Check</th>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">Alert Threshold</th>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">How to Implement</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Prometheus</td>
<td style="padding: 13px; border: 1px solid #ddd;"><code>node_timex_offset_seconds</code> (via <code>node_exporter</code>)</td>
<td style="padding: 13px; border: 1px solid #ddd;">Offset > 0.5 s</td>
<td style="padding: 13px; border: 1px solid #ddd;">Add <code>timex</code> collector to <code>node_exporter</code>.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Grafana</td>
<td style="padding: 13px; border: 1px solid #ddd;">“Clock Drift” panel (graph of offset over time)</td>
<td style="padding: 13px; border: 1px solid #ddd;">Persistent drift > 2 s</td>
<td style="padding: 13px; border: 1px solid #ddd;">Create alert channel to Slack/Email.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Health‑check endpoint</td>
<td style="padding: 13px; border: 1px solid #ddd;">Custom script returning <code>clockSync: true/false</code></td>
<td style="padding: 13px; border: 1px solid #ddd;"><code>false</code> → repeat every 5 min</td>
<td style="padding: 13px; border: 1px solid #ddd;">Add a tiny Node.js script inside the n8n container.</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">Kubernetes</td>
<td style="padding: 13px; border: 1px solid #ddd;">Liveness probe that checks <code>date -u</code> against NTP</td>
<td style="padding: 13px; border: 1px solid #ddd;">Failure → pod restart</td>
<td style="padding: 13px; border: 1px solid #ddd;">Use a sidecar container that runs the check.</td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 2em; line-height: 1.9;">In a high‑throughput cluster, run a dedicated “time‑sync sidecar” that constantly monitors offset and can automatically restart the n8n pod if drift exceeds 1 s.</p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">6. Advanced Troubleshooting Scenarios</h2>
<h3 style="margin-bottom: 45px; line-height: 1.3;">6.1 Intermittent Drift Only During Heavy Load</h3>
<p style="margin-bottom: 2em; line-height: 1.9;"><em>Root cause:</em> CPU throttling under cgroup limits.</p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Fix:</strong> Give the container more CPU resources:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;">services:
n8n:
deploy:
resources:
limits:
cpus: "2.0"</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">6.2 Drift After System Sleep / Hibernation</h3>
<p style="margin-bottom: 2em; line-height: 1.9;"><em>Root cause:</em> Host resumes without re‑syncing NTP.</p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Fix:</strong> Create a systemd service that forces a time step on resume:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;"># /etc/systemd/system/chrony-resume.service
[Unit]
Description=Force chrony to correct time after resume
After=suspend.target</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;">[Service]
Type=oneshot
ExecStart=/usr/bin/chronyc makestep</pre>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;">[Install]
WantedBy=suspend.target</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Enable it with <code>systemctl enable chrony-resume.service</code>.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">6.3 Webhook “Signature expired” Only for Specific Providers</h3>
<p style="margin-bottom: 2em; line-height: 1.9;"><em>Root cause:</em> Provider (e.g., Stripe) uses a stricter 5‑second window, while n8n’s clock is a few seconds ahead.</p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Fix:</strong> Ensure the request timestamp comes from a proxy that is NTP‑synced. Set the tunnel URL accordingly:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; margin-bottom: 2em;"># Example environment variable
N8N_WEBHOOK_TUNNEL_URL=https://my‑proxy.example.com</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">The proxy adds <code>X-Forwarded-Proto</code> and its own timestamp, keeping the validation window happy.</p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">7. Fix n8n Clock Drift in Minutes: CheckList</h2>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">Step</th>
<th style="padding: 13px; border: 1px solid #ddd; text-align: left;">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">1</td>
<td style="padding: 13px; border: 1px solid #ddd;"><code>date -u</code> – confirm host UTC ≤ 2 s offset</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">2</td>
<td style="padding: 13px; border: 1px solid #ddd;">Restart NTP (<code>systemctl restart chronyd</code> or <code>ntp</code>)</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">3</td>
<td style="padding: 13px; border: 1px solid #ddd;">Verify container time: <code>docker exec <c> date -u</code></td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">4</td>
<td style="padding: 13px; border: 1px solid #ddd;">Mount host timezone files into container (see docker‑compose snippets)</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">5</td>
<td style="padding: 13px; border: 1px solid #ddd;">Ensure DB server time matches host</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">6</td>
<td style="padding: 13px; border: 1px solid #ddd;">Set <code>N8N_TIMEZONE=UTC</code> in env</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">7</td>
<td style="padding: 13px; border: 1px solid #ddd;">Re‑deploy n8n container (<code>docker compose pull && up -d --force-recreate</code>)</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">8</td>
<td style="padding: 13px; border: 1px solid #ddd;">Add Prometheus <code>node_timex_offset_seconds</code> alert (< 0.5 s)</td>
</tr>
<tr>
<td style="padding: 13px; border: 1px solid #ddd;">9</td>
<td style="padding: 13px; border: 1px solid #ddd;">Test a cron workflow and a webhook to confirm normal timing</td>
</tr>
</tbody>
</table>
<h2 style="margin-bottom: 45px; line-height: 1.3;"></h2>
Step by Step Guide to solve n8n clock sync time drift issues
Who this is for: Ops engineers, DevOps teams, and n8n administrators who run scheduled workflows or webhook integrations in production. We cover this in detail in the n8n Architectural Failure Modes Guide.
Quick Diagnosis
Problem: n8n’s scheduled workflows run early, late, or skip entirely because the server’s clock has drifted away from real time.
Quick fix:
Verify the host’s time (must be UTC and within 2 seconds).
Restart the host’s NTP service.
Restart the n8n container.
It often appears after a VM pause or a brief network hiccup that stalls NTP.
If the drift reappears, follow the detailed steps below.
1. Why Clock Sync Matters for n8n?
If you encounter any n8n failures under network partitions resolve them before continuing with the setup. Accurate time underpins all time‑sensitive features in n8n.
n8n Feature
Dependency on Accurate Time
Cron / Schedule Trigger
Executes when now >= nextTrigger.
Webhooks with expiresAt
Validates request timestamps.
Credential OAuth token refresh
Calculates expires_in.
Execution logs & audit
Stores ISO‑8601 timestamps.
External APIs (e.g., Stripe, PayPal)
Require request timestamps within ±5 s.
When the OS clock drifts, each component inherits the error, leading to missed runs, duplicate executions, or authentication failures.
Critical – drift can accumulate 1 s/min on idle VMs
Docker containers using host time
Containers inherit host clock; if host drifts, all containers drift
High – isolated containers do not self‑correct
CPU throttling / cgroup limits
Heavy CPU limits can cause the kernel clock to lag
Medium – only in highly constrained environments
Timezone mis‑configuration
n8n runs in UTC, but host set to local TZ, causing conversion errors
Low – usually harmless but can confuse logs
Database server time mismatch
DB clock differs from n8n host
High – execution timestamps stored in DB become inconsistent
Virtualized cloud instances
Some cloud VMs have coarse time sync
Medium – enable chrony or ntp in the VM
4. Step‑by‑Step Diagnosis & Fixes
4.1 Verify Host Time & NTP Status
Run these commands on the host to see the current UTC time and NTP health:
# Show current UTC time
date -u
# Check chrony synchronization status
chronyc tracking
# If you use ntp instead of chrony
ntpq -p
On production servers, enforce chrony with maxdelay 0.5 to guarantee sub‑second accuracy.
If the offset is > 2 seconds, restart the NTP daemon:
# For chrony
sudo systemctl restart chronyd
# For ntp
sudo systemctl restart ntp
4.2 Confirm Docker Container Time
Check that the n8n container sees the same UTC time as the host:
docker exec -it <n8n_container> date -u
If the container’s time differs, the host is still off or the container isn’t sharing the host’s timezone files. Without those mounts the container falls back to its own clock, causing the mismatch.
Fix the mount configuration (docker‑compose excerpt):
These mounts ensure the container uses the host’s clock and timezone.
4.3 Check Database Server Clock
Run the appropriate query on your DB server:
-- Postgres
SELECT now() AT TIME ZONE 'UTC';
-- MySQL
SELECT UTC_TIMESTAMP();
If the DB time diverges, sync the DB host with the same NTP method you used for the n8n host.
4.4 Align n8n’s Internal Timezone
Set the environment variable to force UTC throughout n8n:
# In .env or docker‑compose
N8N_TIMEZONE=UTC
This eliminates any surprises caused by local‑timezone conversions.
4.5 Re‑deploy n8n After Sync
Pull the latest image and recreate the container so it reads the corrected clock:
docker compose pull n8n
docker compose up -d --force-recreate n8n
A clean redeploy is usually faster than hunting for hidden timezone caches. A fresh start guarantees the updated system time is applied.
5. Preventive Monitoring & Alerts
Proactively catch drift before it hurts your workflows.
Tool
Metric / Check
Alert Threshold
How to Implement
Prometheus
node_timex_offset_seconds (via node_exporter)
Offset > 0.5 s
Add timex collector to node_exporter.
Grafana
“Clock Drift” panel (graph of offset over time)
Persistent drift > 2 s
Create alert channel to Slack/Email.
Health‑check endpoint
Custom script returning clockSync: true/false
false → repeat every 5 min
Add a tiny Node.js script inside the n8n container.
Kubernetes
Liveness probe that checks date -u against NTP
Failure → pod restart
Use a sidecar container that runs the check.
In a high‑throughput cluster, run a dedicated “time‑sync sidecar” that constantly monitors offset and can automatically restart the n8n pod if drift exceeds 1 s.