Monitor

What to watch, and which readings lie.

Docs / Run a node / Monitor

What to watch on a node you run, and which readings are not what they look like.

The four readings that matter

ReadingHowHealthy
Heighteth_blockNumberAdvancing, and within a few blocks of a public endpoint
Peersnet_peerCountNon-zero and stable
Genesiseth_getBlockByNumber("0x0")0xd86d57a899cbfa580669f0e1c7cd4ae5f525247c3c823f8f75df176a0c5d7f1a
Memoryjstat -gcutil <pid>Old generation not pinned near 100%, full collections rare

Readings that lie, and what to do instead

A node that does not answer is not a node reporting zero. While a node is catching up it may not answer RPC at all. A height or peer count read as zero in that moment measures nothing. Treat "no answer" as its own state, and when the node may be down, read the log rather than the RPC.

"It advanced once" is not "it is keeping up". A node can import one block from its own database and then sit frozen with no peers. A liveness check needs three things at once: peers non-zero, a minimum amount of growth, and both measured across the whole window rather than at its ends.

An empty block is not a stall. The chain produces a block every half second whether or not there are transactions, so most blocks carry none. Liveness is the height advancing, not the transaction count.

Comparing against a public endpoint fails when the endpoint is the one that is behind. If your reference is itself stuck, a comparison declares your healthy node unhealthy. When the reference is behind, judge by local progress instead.

Disk

Headers are roughly 95% of the database on this chain, and anchor headers are large. Measure growth as size divided by height over the life of the database, with du on the directory, not with df on the filesystem. A compacting database reports wildly different rates over short windows.

Logs

EIP-4788 beacon roots is active in genesis and the beacon roots contract has no code on this chain, so the system call fails on every block. It is a logging condition, not a consensus one. Filter that one message rather than silencing the class, so that real errors from the same component still reach you. A log that is permanently full of errors trains its reader to ignore it.