Pakkit.net
← Back to blog

Operations

A Field Guide to a Distributed Database's Health Signals

Asking whether the database is up is the least useful health question there is, because a distributed database is usually up and quietly struggling — so here are the signals that tell you how it's really doing, and why backpressure matters more than a green light.

  • Operations
  • Databases
  • Monitoring
  • Distributed Systems

When someone asks “is the database healthy?” and checks whether it responds to a connection, they’ve asked the one question that almost never catches the real problem. A distributed database is rarely cleanly up or cleanly down — it’s usually up and struggling in some specific way, and the struggle shows in signals that a connection test can’t see. Here’s the field guide I actually use to read one of these clusters, and the theme underneath it: watch the backpressure, not the front door.

”Up” is the least informative signal

A node answering a query proves it’s running. It says nothing about whether it’s keeping up, falling behind, or one push away from tipping over. Distributed databases degrade gradually — a node gets slow, a queue backs up, replication lags — long before anything goes fully down, and by the time the “is it up?” check fails, you’re not doing diagnosis anymore, you’re doing incident response. This is a ping is not a health check at database scale: reachability and health are different questions, and the interesting one is health. So the real signals are the ones that reveal strain.

The signals worth reading

  • Node membership: who’s up, from whom? These systems gossip about each other’s state, and the first real check is whether every node agrees on who’s in the cluster. A node that this node thinks is down — but that’s actually fine — is a communication problem (network, overload) as much as a node problem. Disagreement about membership is an early smell.
  • Pending compactions: the backlog of deferred work. Because cheap writes defer their cost to compaction, a growing compaction backlog is one of the clearest “this node is underwater” signals there is. A little is normal; a number that climbs and doesn’t drain means the node can’t keep up with its own write load, and reads will get slower as unmerged data piles up.
  • Thread-pool backpressure and dropped work. Internally these databases route work through bounded queues (for reads, writes, and internal tasks). When a queue fills, requests start pending and then get dropped. Pending-and-dropped counts are gold: they tell you the node is taking on more than it can process — the definition of backpressure — often well before latency looks alarming.
  • Latency percentiles, not averages. Look at the tail (p95/p99), not the mean. Averages hide the slow requests, and in a system where a query waits on the slowest replica it touches, the tail is the user experience — which is the whole reason the slowest replica sets your latency.
  • Heap and GC pressure. Many of these run on the JVM, and a node spending more and more time paused for garbage collection will get slow and flaky in ways that look like everything-is-wrong. Rising GC pause time is a root-cause signal masquerading as a dozen symptoms.
  • Replication lag and hinted handoff. When a node is unreachable, its peers stash writes meant for it (hints) to replay later. A pile of stored hints means a node has been missing writes — the data will reconcile, but it’s a sign something was out, and it’s part of the homework eventual consistency quietly does.

Read them together, not one at a time

No single number tells the story; the diagnosis is in the combination. Rising GC pauses plus climbing pending compactions plus growing dropped-message counts on one node is a clear picture: that node is overloaded and falling behind, and it’ll start dragging query latency for anything that touches it. The same latency spike with a healthy node picture points somewhere else entirely — the client, the network, a hot partition. Reading the signals together is what separates “the database is slow” (useless) from “this node is GC-thrashing and can’t drain compactions, so its replica responses are lagging” (actionable).

The trap: a hot node that looks like a sick cluster

One pattern worth calling out because it fools people: one node shows all the strain signals — high latency, backpressure, climbing queues — and the instinct is “that node is failing.” Sometimes. But just as often the node is fine and it’s simply receiving too much, because the client’s routing is aiming most of the traffic at it. The health signals are real, but the cause is upstream. So when one node looks sick and the rest look bored, check the load distribution before you go replacing hardware.

Watch strain, and the outages get boring

The point of all this is to catch the cluster struggling rather than failed, because a struggling cluster is a tuning conversation and a failed one is a 3am page. Backpressure signals — pending work, dropped messages, compaction backlog, GC pauses, tail latency — are leading indicators; “is it up?” is a lagging one. Wire your monitoring to the leading indicators and most database incidents turn into things you noticed and eased off before anyone downstream felt them. That’s the whole game: read the strain early, and the failures never get a chance to be interesting. If you’ve got a health signal on this list you swear by (or one I missed), I’d like to hear it.