diff --git a/RUN-A-NODE.md b/RUN-A-NODE.md index 39fec1e..fcf31cb 100644 --- a/RUN-A-NODE.md +++ b/RUN-A-NODE.md @@ -158,6 +158,23 @@ the network's reading nodes, and validates every hybrid anchor there, since 2026 --- +## Sizing the JVM heap: bigger is not faster + +Measured 2026-09-06 on one machine, one database, one chain, inside a single hour, syncing chain 2800 +from genesis in a Linux VM with 8 GB of RAM: + +| `-Xmx` | what happened | blocks per minute | +| --- | --- | --- | +| 4500m | 89 `OutOfMemoryError`, process at 7.1 GB RSS, import stopped dead | 0 | +| 3200m | still 24 OOM per 500 log lines, repeated `Chain download failed` | ~1,500 | +| 2400m | no OOM at all | ~82,000 | + +The reason is that **heap is not the same as memory**: Besu's storage engine keeps its block cache and +its write buffers OUTSIDE the Java heap, and at six million blocks that off-heap part is larger than the +heap itself. A heap sized to fill the machine leaves nothing for it, and the node spends its time in GC +and failed downloads instead of importing. Give the JVM roughly a third of the RAM you have, not all of +it, and leave the rest to the database and the operating system. If you see `OutOfMemoryError` in the +log, the first thing to try is a SMALLER `-Xmx`, not a larger one. ## The configuration a follower passes (BESU_OPTS) The Aere fork reads its per-node configuration from JVM system properties passed through the