0 XP · 0 scenes

Heartbeats and failure detection

Distributed Systems Core · lesson 4 of 11 · about 28 min

Heartbeats and failure detection

How a machine knows another has died, and why it can never be sure: the timeout trade-off measured as false alarms against detection time, an adaptive phi accrual detector, failures that answer pings but fail real work, what monitoring topologies cost, and what a long pause does to a leader holding a lease. Tap any for a plain-language card.

0 / 8 sections done
  1. 1The timeout dial5 min
  2. 2Phi accrual5 min
  3. 3Gray failure4 min
  4. 4Who watches whom4 min
  5. 5Pick the setting3 min
  6. 6Who lives by this1 min
  7. 7Interview angle2 min
  8. 8Break It: the long pause4 min

Words in this lesson12Tap one for its meaning.

The timeout dial

You cannot tell a dead machine from a slow network. You can only guess.

This is the problem, and it has no perfect solution in an asynchronous network. The simulation sends 40,000 heartbeats with log-normal delay, random loss and occasional congestion stalls (released all at once, as real queues do), and counts false alarms per hour and the time to notice a real crash, for different numbers of allowed missed beats.

With 1-second beats and 2.5 s stalls, 2 allowed misses gives dozens of false alarms an hour; 6 gives none but takes 5 seconds to notice a crash.

  • 1 miss (1.0 s)
    1781.4/h · 0.4 s
  • 2 misses (2.0 s)
    94.9/h · 1.4 s
  • 3 misses (3.0 s)
    7.5/h · 2.4 s
  • 4 misses (4.0 s)
    0.5/h · 3.4 s
  • 6 misses (6.0 s)
    0.0/h · 5.4 s
  • 8 misses (8.0 s)
    0.0/h · 7.4 s
False alarms per hour7.5
Real crash noticed after2.44 s
Slowest 1% of crashes2.99 s

Declaring death after 3 missed beats (3.0 s) raises 7.5 false alarms an hour and notices a real crash in 2.44 s on average. Each bar shows another choice: more misses allowed means calmer but slower. There is no setting that is both instant and never wrong.

Seeded simulation: 40,000 heartbeats, 20 ms median delay (log-normal), your loss and stall settings. A false alarm is a gap between arrivals longer than the timeout.

Phi accrual

Instead of “alive or dead”, report how suspicious the silence is.

That fixes the main weakness of a fixed timeout: in a calm network a 3-second timeout is far too slow (heartbeats arrive within 60 ms of schedule), and in a noisy one it is too short. The graph shows phi growing as a beat is late for a calm window (mean 1 s, deviation 60 ms); the table runs both detectors through a calm and then a noisy regime.

Compare detection time in the calm regime, then raise the stall length and the threshold.

phi (0 to 16) against time since the last beat (0.9 to 2 s) · green = your threshold, crossed at 1337 ms
RegimeFixed: false alarms/hFixed detects inPhi: false alarms/hPhi detects in
Calm network0.03.0 s0.01.11 s
Noisy network7.23.0 s15.12.46 s
Calm: phi vs fixed detection1.1 s vs 3.0 s
Noisy: phi window learns2.5 s
Noisy false alarms (phi / fixed)15 / 7

In the calm regime phi (threshold 8) notices a crash in about 1.11 s against 3.0 s for the fixed timeout, because it learned that beats are very regular. In the noisy regime it widens by itself to 2.46 s. Its false alarms (15 an hour) depend on the threshold: raise it to trade speed for calm. Cassandra's default is 8.

Phi uses the last 500 gaps, assumed normally distributed. Heavy-tailed stalls are harder than normal jitter, which is why a high threshold matters.

Gray failure

The process is up, the port answers, and one request in three fails.

The fix is the deep health check: instead of “is the port open”, perform a small real operation (touch the database, read a key) and require a few failures in a row before acting. Below, a node fails a fraction of real requests. A shallow ping never notices; a deep check finds it after k consecutive failed checks. Compare the requests lost.

Set 30% failures with a deep check needing 3 in a row: found in seconds. The shallow ping would run for an hour.

  • Shallow ping: failed requests in an hour
    216,000
  • Deep check: failed requests before removal
    2,400
Shallow ping sayshealthy
Deep check removes it after40 s
Requests saved213,600

A node failing 30% of 200 requests a second keeps answering pings, so a shallow check leaves it in service and 216,000 requests fail in an hour. A deep check needing 3 failures in a row (every 2 s) removes it after about 40 s with 2,400 requests lost. Raising N reduces false alarms but delays removal: the timeout dial again.

Each check fails with the node's failure probability; the node is removed after N consecutive failed checks. Seeded.

Who watches whom

If everyone pings everyone, the heartbeats become the biggest traffic in the cluster.

The other cost is disagreement. Failure detection is local opinion. If a partition splits the cluster into a group of 150 and a group of 350, each side concludes that the other side is dead. A central monitor on one side calls the other side dead too. That is exactly the situation consensus protocols and fencing exist to handle safely: never act on a single node's opinion alone.

Set 500 nodes at 1-second beats and compare all-to-all with a ring.

  • All-to-all
    250K/s
  • Gossip (3 peers each)
    1.5K/s
  • Ring (2 neighbours)
    1K/s
  • Central monitor
    500/s
All-to-all250K/s
Ring or gossip1K to 1.5K/s
Ratio all-to-all ÷ ring250×

All-to-all monitoring at 500 nodes sends 250K messages a second; a ring needs 1K. After a partition of 150 | 350, the 150 nodes believe 350 nodes are dead and the 350 believe 150 are dead: both sides are sure, both are partly wrong. A central monitor on the larger side would also declare 150 dead.

Arithmetic: all-to-all N(N−1) per interval, ring 2N, central N, gossip with 3 peers 3N. Responses not counted.

Pick the setting

Six clusters, three styles.

Choose the failure detection that fits what a false alarm and a late alarm cost. Each answer is worth 20 XP.

Ask: what does a false alarm cost? and what does a late detection cost?

Question 1 / 6

A cache cluster in one data centre where removing a healthy node only costs some cache misses.

Tip: press 1 to 3 to answer, Enter for the next one.

Who lives by this

Production clusters publish their detection settings.

Four real systems and the failure-detection numbers they document.

The 2004 paperHayashibara et al.

phi accrual failure detector

The phi accrual paper proposed outputting a continuous suspicion level, phi, computed from the distribution of recent heartbeat arrival times, instead of a boolean, and letting each application choose its own threshold. It showed good trade-offs between detection time and mistakes under varying network conditions.

Threshold 8 by defaultApache Cassandra

gossip heartbeats → phi accrual → convict at 8

Cassandra uses a phi accrual detector over its gossip heartbeats, with phi_convict_threshold defaulting to 8, and documents raising it (for example to 12) in cloud environments with noisy networks to avoid marking nodes down by mistake.

Leases as heartbeatsKubernetes

kubelet → Lease every 10 s → controller grace period 40 s

Each Kubernetes node renews a Lease object about every 10 seconds, and the node controller marks a node unhealthy only after the node-monitor-grace-period, 40 seconds by default, passes without an update. The grace period is the timeout dial set to four missed beats.

Health checks you configureAWS load balancers

interval 30 s · unhealthy after 2 failures

AWS documents health checks on load balancer target groups with a configurable interval (30 seconds by default), and thresholds for how many consecutive failures mark a target unhealthy and how many successes bring it back. The defaults mean roughly a minute to react: a deliberate bias toward calm over speed.

Interview angle

What interviewers actually ask.

Six questions, each worth 20 XP. “How do you detect a failed node?” is a standard probe of distributed-systems depth.

Name the trade-off (false alarms vs detection time), say how you would pick the timeout, and mention deep health checks.

Question 1 / 6

Why can a failure detector never be perfect in an asynchronous network?

Tip: press 1 to 3 to answer, Enter for the next one.

Break it

A long garbage-collection pause makes the leader's lease expire, and it never noticed.

Pauses are usually milliseconds, but real systems have a long tail (Martin Kleppmann's well-known critique of lock services describes exactly this). A longer lease makes it rarer but slows failover, since nobody can take over until the lease expires. The robust fix is not a better timeout but a : every grant gets an increasing number, and storage rejects writes carrying an older one, so the revived old leader's writes are refused. The next-but-three lesson builds on this.

With a 10-second lease and a 2-in-1,000 chance of a 15-second pause, a few overlaps a day. Then switch fencing on.

Leases outlasted by a pause0.195%
Two-leader episodes per day16.8
Average overlap6.1 s

With a 10 s lease, 0.195% of leases are outlasted by a pause: about 16.8 episodes a day (one renewal every 10 s), each leaving two leaders for roughly 6.1 s. A longer lease shrinks that, and makes failover slower by the same amount.

100,000 seeded leases; pause = log-normal body plus an occasional long stall. One renewal every 10 seconds assumed for the per-day figure.

Where to go next