CMD Guide
HomeSystem DesignSystem Design Building Blocks

Heartbeat

A heartbeat lets a monitor infer that a process is alive not by asking it, but by requiring it to keep proving liveness — the process emits a tiny "I'm still here" message on a fixed interval, and the monitor concludes failure only from the absence of those messages past a timeout, because over an asynchronous network you can never positively distinguish a crashed node from a slow or partitioned one — you can only wait and give up.

That single fact — you detect failure by waiting, not by observing it — drives every design decision. Two knobs control the mechanism: the interval Δt (how often a beat is sent, e.g. 1 s) and the timeout T (how long silence is tolerated, usually a small multiple of Δt, e.g. 3·Δt). Shrink them and you detect crashes faster but wrongly accuse healthy-but-slow nodes; grow them and you stop the false accusations but a truly dead node keeps receiving traffic longer. This is the core detection-time vs. accuracy trade-off, formalised by Chandra & Toueg as completeness (every real crash is eventually detected) versus accuracy (no live node is wrongly suspected) — no timeout-based detector can maximise both.

Two topologies exist. Centralized: every node beats to one monitor (simple, but the monitor is a bottleneck and single point of failure). Kubernetes is the canonical centralized example: every kubelet heartbeats a Lease object (in the kube-node-lease namespace, renewed every ~10 s) to the API server, and a central node controller convicts the node after a grace period — the monitor bottleneck is mitigated by making it an HA control plane rather than by gossip. Peer / gossip: each node beats to a random subset of peers and suspicion spreads epidemically (no central bottleneck, scales to thousands, but membership state is only eventually consistent). Cassandra, Akka Cluster and Consul (via Serf/SWIM) use variants of the peer model.

diagram
diagram

Worked trace: one node, one monitor

Monitor M watches node S. Δt = 1 s, timeout T = 3 s (declare dead after 3 s of silence). S beats at t = 0,1,2,3,4 then crashes at t ≈ 4.4 s. M keeps a lastSeen timestamp and, on its own clock, checks now − lastSeen > T.

Wall clockEventM.lastSeennow − lastSeenM's verdict
0–4 sbeats arrive on scheduleupdated each beat≤ 1 sALIVE
4.4 sS crashes (M can't see this)4.00.4 sALIVE
5.0 sbeat #5 missed4.01.0 sALIVE
6.0 sbeat #6 missed4.02.0 sALIVE (suspicious)
7.0 sbeat #7 missed → timeout crossed4.03.0 sDEAD → reroute / start replacement

Note the two costs baked in: detection latency is ≈ 2.6 s (crash at 4.4, detected at 7.0), and traffic sent to S between 4.4 and 7.0 is silently lost or must be retried elsewhere.

Why the naive version is wrong. A tempting simplification is "missed one beat ⇒ dead" (T = Δt). But real inter-arrival times jitter from network queueing, TCP retransmits and scheduler stalls. A single delayed packet then evicts a perfectly healthy node, triggering a needless failover — and if the node is a shard leader, a spurious leader election. That is why T is always a multiple of Δt, and why the better answer below stops using a hard threshold at all.

The GC-pause false positive, and the φ-accrual fix

The classic killer of fixed timeouts: a JVM (or Go runtime) stop-the-world garbage-collection pause of 2–4 s freezes everything, including the heartbeat sender thread. The node is perfectly healthy — it just couldn't emit a beat — yet a 3 s timeout convicts it. Under load these pauses cluster, so the whole cluster can start flapping (nodes marked down, marked up, rebalancing, marked down again). A hard binary threshold has no way to say "this silence is a bit unusual but not yet alarming."

The φ-accrual failure detector (Hayashibara et al., 2004; used by Cassandra and Akka) replaces the yes/no timeout with a continuously rising suspicion level φ. It records the recent history of inter-arrival times, fits a distribution (mean μ, std σ), and reports

φ(now) = −log₁₀( P(next beat arrives later than the elapsed silence) )

φ = 1 means ~10% chance the silence is normal; φ = 8 means ~10⁻⁸. The application picks a threshold (Cassandra's default phi_convict_threshold = 8) and — crucially — φ self-tunes: on a jittery WAN link where beats are naturally late, μ and σ grow, so a 2 s gap yields a low φ and no conviction; on a rock-steady LAN the same 2 s gap yields a high φ and fast conviction. Same code, adapts to each link.

Worked numbers, μ = 1000 ms, σ = 200 ms (modelled normal):

Silence elapsedz = (t−μ)/σP(later)φvs. threshold 8
1200 ms10.1590.80alive
1600 ms31.3×10⁻³2.87alive
2000 ms52.9×10⁻⁷6.54alive (rising fast)
≈2130 ms5.6510⁻⁸8.0convict
diagram
diagram

Pitfalls

When to use it — and when to reach for something else

Reach for a heartbeat when nodes need continuous, low-latency liveness signals about each other — leader/follower health, shard-owner tracking, load-balancer backend pools, session keep-alive. Concrete signal: you must detect a dead peer within seconds and take automated action (reroute, fail over, re-replicate), and you control both ends of the connection.

Binary timeout vs. φ-accrual. Binary is trivial to implement and reason about — choose it on a controlled LAN with predictable latency and tolerant timeouts. Choose φ-accrual when link quality varies (WAN, cloud AZs, GC-heavy runtimes) and false positives are expensive; you pay a little history-tracking state and lose the crisp "dead at exactly T" guarantee in exchange for adaptivity.

Centralized vs. gossip/SWIM. Centralized monitoring is fine up to a few dozen nodes and when you already have a coordinator. Past that, prefer gossip-style peer heartbeats (SWIM: ping + indirect ping via k relays) — it removes the single monitor, spreads load evenly, and scales to thousands, at the cost of only eventually consistent membership and harder debugging.

Named alternatives and the trade-off

Choose a heartbeat when you need proactive, sub-10-second liveness and you own the endpoints; prefer ZooKeeper/etcd leases when the detection must drive cluster-wide agreement; prefer gossip/SWIM when N is large; fall back to TCP keepalive / circuit breakers when failures are rare and reactive detection is acceptable.

Takeaways


Re-authored / deepened for this guide. Sources: Grokking the System Design Interview (Design Gurus) heartbeat pattern; Naohiro Hayashibara et al., "The φ Accrual Failure Detector" (SRDS 2004) and Apache Cassandra's FailureDetector / phi_convict_threshold; Tushar Chandra & Sam Toueg, "Unreliable Failure Detectors for Reliable Distributed Systems" (JACM 1996) for completeness vs. accuracy; Das, Gupta & Motivala, "SWIM: Scalable Weakly-consistent Infection-style Membership" (DSN 2002); Wei Chen et al. on the quality of service of failure detectors; and Kubernetes liveness/readiness probe semantics.

🤖 Don't fully get this? Learn it with Claude

Stuck on Heartbeat? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Heartbeat** (System Design) and want to truly understand it. Explain Heartbeat from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Heartbeat** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Heartbeat** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Heartbeat** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes