Distributed & Decentralized Systems Curriculum
Time Causality · Physical Clock Drift

Key Question

Why do computers tell different times, and how badly do their clocks disagree?

Deep Dive

Inside almost every computer is a small sliver of quartz crystal shaped like a tuning fork. When an electric current is applied, the crystal vibrates at a precise mechanical resonance frequency — typically 32,768 Hz for consumer devices. These vibrations are counted by a circuit, and the count becomes the computer’s sense of time. The problem is that no two crystals vibrate at exactly the same frequency. The difference is tiny — measured in parts per million (ppm) — but it accumulates into real disagreements over hours and days.

The root cause is manufacturing variance. Quartz crystals are cut from a larger crystal, and slight differences in the angle of the cut, impurities in the material, and the shape of the finished crystal all affect the resonant frequency. Temperature is the largest environmental factor. A crystal that is perfectly accurate at 25 degrees Celsius may gain or lose 0.04 ppm for every degree of temperature change. The crystal in your laptop, sitting on a desk at a comfortable room temperature, drifts differently than one in a server rack where temperatures fluctuate by 10 degrees as cooling fans cycle on and off. Age also matters: crystals slowly change frequency over years of use.

Two terms describe the disagreement between clocks. Clock skew is the instantaneous difference between two clocks at a point in time. If clock A reads 10:00:00.000 and clock B reads 10:00:00.050, the skew is 50 milliseconds. Clock drift is the rate at which skew changes over time. A clock that drifts at 1 ppm gains or loses 1 microsecond per second. That may sound negligible, but it adds up: 1 ppm = 86 milliseconds per day = about 2.6 seconds per month = 31.5 seconds per year.

Clock A:  ────+────+────+────+────+  (perfect, 1 tick per second)
              |    |    |    |    |
Clock B:  ────+----+----+----+----+  (drifts, 1.000001 ticks per second)
                ^
                After 1,000,000 seconds,
                Clock B has gained 1 second

A more intuitive formula: the error over time for a clock that drifts at rate D (in ppm) is:

Error = D × 10^-6 × elapsed_time

Example: D = 20 ppm, elapsed = 30 days = 2,592,000 seconds
Error = 20 × 10^-6 × 2,592,000 = 51.84 seconds

A clock that drifts 20 ppm will be off by nearly a minute after a single month. This is why computers do not rely on their quartz crystals for long-term accuracy. They synchronize with external time sources using protocols like NTP, or they accept the consequences of drift.

Different applications tolerate different amounts of clock error. A video game with a 30-second countdown timer can tolerate seconds of error. A financial trading system that timestamps trades must have sub-millisecond accuracy — a trade that happens at 10:00:00.001 on one server and 10:00:00.000 on another will be ordered incorrectly, potentially causing financial losses. A distributed database that relies on timestamps for conflict resolution will silently corrupt data if clocks disagree beyond its tolerance.

Check Your Understanding

  1. A quartz crystal has a drift rate of 10 ppm. How much error accumulates in 7 days?
  2. What is the difference between clock skew and clock drift?
  3. Why does temperature affect clock accuracy, and what does this mean for servers in different parts of a data center?

The “So What?”

If you have ever seen a “clock skew detected” message in a database log, you have encountered this lesson in practice. Clock drift is not an abstract curiosity — it is a concrete source of bugs that corrupts data, breaks ordering assumptions, and causes authentication tokens to expire early. Every distributed system engineer should know that drift exists, how to estimate its magnitude, and when it matters for their application.


✏️ Exercises

Topic 2: Physical Clock Drift — Exercises

Exercise 1: Drift Accumulation

A server room experiences a cooling failure. The temperature rises by 15 degrees Celsius, causing the quartz crystals in the servers’ clocks to drift at 20 ppm instead of their normal 5 ppm. The cooling outage lasts 30 days.

How much clock error accumulates during this period? Express your answer in seconds.


Exercise 2: Cristian’s Algorithm Error Bound

A client uses Cristian’s algorithm to synchronize with a time server. The client makes three requests and gets these results:

RequestT1 (client send)T_server (server time)T2 (client receive)
1010,000,000120
250010,000,100540
3100010,000,2001040

(a) Calculate the estimated server time for each request. (b) Which request gives the most accurate estimate? Why? (c) If the actual one-way delay from client to server is 50ms and from server to client is 10ms for the best request, what is the true server time at T2, and what is the error of Cristian’s estimate?


Exercise 3: Berkeley Algorithm Arithmetic

A cluster of 5 machines runs the Berkeley Algorithm. The master polls the slaves and receives these time offsets (in seconds from the master’s perspective at the moment of polling):

MachineOffset (seconds)
Master+1.00
Slave 1+0.50
Slave 2-0.75
Slave 3+0.25
Slave 4+5.00

(a) Identify any outliers. What threshold would you use? (b) Compute the fault-tolerant average. (c) Compute the adjustment for each machine. (d) What would happen to the cluster’s time if the Berkeley Algorithm were NOT used and each machine relied on its own quartz crystal?


Exercise 4: NTP Slewing vs. Stepping

A database server generates timestamps for every write. Its clock is wrong by +800 ms (it is 800 ms ahead of UTC). The NTP daemon has two options:

Option A: Step the clock backward by 800 ms immediately. Option B: Slew the clock at a rate of 50 ppm (50 microseconds per second) until it reaches the correct time.

(a) How long does Option B take to correct the 800 ms error? Show the calculation. (b) During Option A, describe the exact problem that can occur with database timestamps. (c) Which option would you choose for a system that assigns monotonically increasing transaction IDs? Why?

👁️ View Solutions

Topic 2: Physical Clock Drift — Solutions

Solution 1

Drift rate: D = 20 ppm = 20 × 10⁻⁶

Elapsed time: 30 days = 30 × 24 × 60 × 60 = 2,592,000 seconds

Error = D × 10⁻⁶ × elapsed_time = 20 × 10⁻⁶ × 2,592,000 = 20 × 2.592 = 51.84 seconds

Each server’s clock is off by about 52 seconds after 30 days. This is enough to cause authentication failures (Kerberos tickets typically have a 5-minute tolerance), SSL certificate validation failures, and confusing log timestamps.


Solution 2

(a)

Request 1: RTT = 120 - 0 = 120ms. Estimated = 10,000,000 + 120/2 = 10,000,060 Request 2: RTT = 540 - 500 = 40ms. Estimated = 10,000,100 + 40/2 = 10,000,120 Request 3: RTT = 1040 - 1000 = 40ms. Estimated = 10,000,200 + 40/2 = 10,000,220

(b) Request 2 and 3 both have RTT = 40ms — this ties for the smallest RTT. A smaller RTT suggests less network congestion and makes the symmetric delay assumption more plausible. Both Request 2 and 3 are equally “best” by RTT. However, if we note that Request 3’s estimated time is 10,000,220 with the same RTT, while Request 2’s is 10,000,120, this is simply because the server’s clock advanced between the two requests. The accuracy of the estimate (error from true time) is the same for both since the RTT is the same.

To choose between them, one could compare the variances of previous RTT measurements or simply use the first one with the minimum RTT.

(c) For Request 2: RTT = 40ms, but the true asymmetry is 50ms outbound, 10ms inbound.

True server time at T2 = T_server + inbound_delay = 10,000,100 + 10ms = 10,000,110

Cristian’s estimate = 10,000,120

Error = 10,000,120 - 10,000,110 = 10ms

The estimate is 10ms ahead of the true time. The error is: |inbound_delay - outbound_delay| / 2 = |10 - 50| / 2 = 20ms

But the actual error is 10ms (because of additional processing time). The general formula: maximum error = RTT/2 - min_one_way = 20 - 10 = 10ms.


Solution 3

(a) Outlier detection: The offsets are +1.00, +0.50, -0.75, +0.25, and +5.00. Slave 4’s offset of +5.00 seconds is far outside the range of the other four (which span -0.75 to +1.00). A simple threshold would be: discard any value more than, say, 3 seconds from the median. Slave 4 is clearly faulty — maybe its battery has died.

(b) Fault-tolerant average (excluding Slave 4):

Average = (+1.00 + 0.50 + (-0.75) + 0.25) / 4 = 1.00 / 4 = +0.25 seconds

(c) Adjustments:

Master: +1.00 → +0.25, adjust by -0.75 seconds (slew backward) Slave 1: +0.50 → +0.25, adjust by -0.25 seconds (slew backward) Slave 2: -0.75 → +0.25, adjust by +1.00 seconds (slew forward) Slave 3: +0.25 → +0.25, adjust by 0 seconds (already at average) Slave 4: excluded, not adjusted (but should be diagnosed)

(d) Without the Berkeley Algorithm, each machine’s clock would drift independently. After 30 days:

Master at 5 ppm: off by 5 × 10⁻⁶ × 2,592,000 = 13.0 seconds Slave 1 at 5 ppm: off by 13.0 seconds (in the same direction, perhaps) Slave 2 at 5 ppm: off by 13.0 seconds But if one machine has a crystal with a different drift rate (say 20 ppm due to manufacturing variance), it could be off by 52 seconds — producing a 39-second disagreement between machines. Database timestamps would disagree, logs would be impossible to correlate, and any ordering based on timestamps would be wrong.


Solution 4

(a) Option B (slew at 50 ppm):

50 ppm = 50 × 10⁻⁶ = 0.00005 seconds per second = 0.05 ms per second

To correct 800 ms:

time = 800 ms / (0.05 ms/s) = 16,000 seconds = 4 hours, 26 minutes, 40 seconds

(b) During Option A (step backward by 800ms):

At 10:00:00.000 (server time), the server writes transaction T1 with timestamp 10:00:00.000. NTP steps the clock back to 09:59:59.200 (correct UTC time). The next transaction T2 gets timestamp 09:59:59.200. Now T2 appears to “happen before” T1, even though it came after. Any system that relies on timestamp monotonicity (write-ahead logs, replication slots, MVCC visibility) may fail or corrupt data because the “before” and “after” ordering is reversed.

(c) For a system with monotonically increasing transaction IDs, Option B (slew) is strongly preferred. The 4.5-hour convergence time is acceptable for most applications — it prevents any discontinuity in timestamps. Option A risks data corruption or system crashes. If the error were extremely large (say, hours), the database might require a maintenance window for a stepped correction, but for 800ms, slewing is safe.