System information
Erigon version:
erigon version 3.5.4-28bc52d6
The same behavior was also observed on Erigon 3.4.2.
OS & Version:
Guest: Ubuntu 24.04.4 LTS, Linux 6.8.0-137-generic, x86_64
Host: Proxmox VE 9.2.0, Linux 7.0.14-6-pve, x86_64
VM: 8 vCPU, 40 GiB RAM
Disk: WD_BLACK SN850X 4 TB NVMe
Host filesystem: ext4, noatime
Guest data mount: virtiofs
There is no btrfs, ZFS, or autodefrag layer in the data path. SMART reports no
media or data integrity errors. The node has very low JSON-RPC traffic during
the measurements.
Commit hash: 28bc52d6
Erigon command (addresses shortened; all other relevant flags are unchanged):
/usr/bin/erigon \
--chain=mainnet \
--datadir=/var/lib/eth/erigon \
--authrpc.addr=127.0.0.1 \
--authrpc.port=8551 \
--authrpc.jwtsecret=/var/lib/eth/jwt/jwt.hex \
--http \
--http.addr=<private-ip> \
--http.port=8545 \
--http.api=eth,net,web3,erigon,trace,ots \
--port=30303 \
--torrent.port=42069 \
--nat=stun \
--caplin.nat=stun \
--metrics \
--metrics.addr=<private-ip> \
--metrics.port=6060 \
--sync.loop.block.limit=10000 \
--batchSize=1g \
--caplin.max-peer-count=64
Consensus Layer: embedded Caplin. I also reproduced the execution-layer write
rate with Caplin disabled (--externalcl) and Lighthouse BN 8.2.1 connected to
the Engine API.
Consensus Layer command for the external-CL control:
lighthouse bn \
--network=mainnet \
--datadir=/var/lib/eth/lighthouse \
--execution-endpoint=http://127.0.0.1:8551 \
--execution-jwt=/var/lib/eth/jwt/jwt.hex \
--checkpoint-sync-url=https://mainnet.checkpoint.sigp.io
Chain/Network: Ethereum mainnet
Expected behaviour
I expected steady-state writes at chain tip to be substantially lower than
110-140 MiB of MDBX copy-on-write pages and 160-180 MiB of physical NVMe
writes per execution block, especially while the MDBX file and total database
size remain constant.
If this write volume is expected for Erigon 3 at mainnet tip, please confirm it
and consider documenting the expected steady-state write rate or write
amplification. At the observed rate, the host writes approximately
1.2-1.4 TB/day if the workload remains constant.
Actual behaviour
Erigon stays fully synced and healthy, but continuously writes approximately
13-15 MiB/s to the physical NVMe at chain tip. The write activity continues
without meaningful RPC load and stops when execution stops processing new
blocks.
The strongest 30-minute baseline on Erigon 3.5.4 processed 150 blocks with
zero head lag and zero restarts:
| Metric |
Result |
| Physical NVMe writes |
13.522 MiB/s |
| Physical NVMe writes per block |
162.26 MiB/block |
| MDBX COW writes |
9.166 MiB/s |
| MDBX COW writes per block |
109.99 MiB/block |
| MDBX page splits |
361.59/block |
| MDBX file size delta |
0 |
The following controls were run on the same node and data directory:
| Test |
Duration |
Blocks |
Physical NVMe |
MDBX COW |
Notes |
--externalcl, no CL input |
300s |
0 |
0.369 MiB/s |
0 |
Execution head intentionally static |
| Embedded Caplin |
300s |
25 |
12.30 MiB/s |
10.57 MiB/s |
Chain tip, lag 0 |
| Caplin, parallel execution |
1800s |
150 |
13.522 MiB/s |
9.166 MiB/s |
Chain tip, lag 0 |
Caplin, --exec.serial |
1800s |
149 |
13.358 MiB/s |
10.180 MiB/s |
Chain tip, lag 0 |
| External Lighthouse |
1812s |
151 |
14.955 MiB/s |
11.565 MiB/s |
Chain tip, lag 0; Lighthouse was backfilling |
Normalizing the two 30-minute Caplin execution modes by block:
| Metric |
Parallel |
Serial |
Serial change |
| Physical NVMe write/block |
162.26 MiB |
161.37 MiB |
-0.55% |
| MDBX COW/block |
109.99 MiB |
122.97 MiB |
+11.81% |
| MDBX page splits/block |
361.59 |
415.05 |
+14.78% |
Therefore --exec.serial does not reduce the write amplification. Replacing
Caplin with Lighthouse also does not reduce Erigon MDBX COW. The external
Lighthouse physical-disk result includes its checkpoint backfill, but the MDBX
COW metric is emitted by Erigon and remains high independently of that CL I/O.
During longer observation periods:
mdbx.dat remained approximately 6.26 GiB;
- total
db_size{db="chaindata"} remained constant;
ReclaimableSpace, CommitmentVals, and ChangeSets3 changed in both
directions instead of growing without bound;
db_rotx_overloaded_total remained 0;
- the execution head remained at the public head;
- running Erigon with
--externalcl and no CL input reduced physical writes to
the host background level while the execution head remained static.
This looks like sustained MDBX COW/page-split churn caused by per-block
execution state and commitment updates rather than database growth, Caplin,
pruning backlog, or RPC traffic.
Steps to reproduce the behaviour
- Sync Erigon 3.5.4 on Ethereum mainnet and wait for
eth_syncing=false and
zero public-head lag.
- Wait at least five minutes after catch-up so catch-up execution is excluded.
- Enable Erigon Prometheus metrics and scrape them every 15 seconds.
- Measure an uninterrupted 30-minute chain-tip window.
- Record the start and end execution block numbers and normalize all counters
by the number of processed blocks.
- Calculate MDBX COW bytes from the 16 KiB MDBX page counter:
increase(db_pgops{db="chaindata",phase="cow"}[30m]) * 16384
- Measure physical device writes using node-exporter or Linux diskstats:
increase(node_disk_written_bytes_total{device="nvme0n1"}[30m])
- Confirm that the physical write rate falls to the host background level
when execution is intentionally held static with --externalcl and no CL.
For a control that isolates consensus input, start Erigon with --externalcl
and no CL. MDBX COW remains zero while the execution head is static. Then attach
a synced external CL: MDBX COW returns as execution resumes at chain tip.
Related work
This report may be an operator-visible measurement of the work already tracked
in:
Could you confirm whether 110-140 MiB of MDBX COW per mainnet block is
expected on 3.5.4 and whether these two changes are intended to address this
steady-state write volume? I can provide raw Prometheus series, a longer test
window, selected Erigon logs, or test a specific branch/build if useful.
Backtrace
There is no crash or backtrace. Erigon remains synced, has no automatic
restarts, and logs no errors during the measurement windows.
System information
Erigon version:
The same behavior was also observed on Erigon
3.4.2.OS & Version:
There is no btrfs, ZFS, or autodefrag layer in the data path. SMART reports no
media or data integrity errors. The node has very low JSON-RPC traffic during
the measurements.
Commit hash:
28bc52d6Erigon command (addresses shortened; all other relevant flags are unchanged):
Consensus Layer: embedded Caplin. I also reproduced the execution-layer write
rate with Caplin disabled (
--externalcl) and Lighthouse BN 8.2.1 connected tothe Engine API.
Consensus Layer command for the external-CL control:
Chain/Network: Ethereum mainnet
Expected behaviour
I expected steady-state writes at chain tip to be substantially lower than
110-140 MiBof MDBX copy-on-write pages and160-180 MiBof physical NVMewrites per execution block, especially while the MDBX file and total database
size remain constant.
If this write volume is expected for Erigon 3 at mainnet tip, please confirm it
and consider documenting the expected steady-state write rate or write
amplification. At the observed rate, the host writes approximately
1.2-1.4 TB/dayif the workload remains constant.Actual behaviour
Erigon stays fully synced and healthy, but continuously writes approximately
13-15 MiB/sto the physical NVMe at chain tip. The write activity continueswithout meaningful RPC load and stops when execution stops processing new
blocks.
The strongest 30-minute baseline on Erigon 3.5.4 processed 150 blocks with
zero head lag and zero restarts:
13.522 MiB/s162.26 MiB/block9.166 MiB/s109.99 MiB/block361.59/block0The following controls were run on the same node and data directory:
--externalcl, no CL input300s00.369 MiB/s0300s2512.30 MiB/s10.57 MiB/s01800s15013.522 MiB/s9.166 MiB/s0--exec.serial1800s14913.358 MiB/s10.180 MiB/s01812s15114.955 MiB/s11.565 MiB/s0; Lighthouse was backfillingNormalizing the two 30-minute Caplin execution modes by block:
162.26 MiB161.37 MiB-0.55%109.99 MiB122.97 MiB+11.81%361.59415.05+14.78%Therefore
--exec.serialdoes not reduce the write amplification. ReplacingCaplin with Lighthouse also does not reduce Erigon MDBX COW. The external
Lighthouse physical-disk result includes its checkpoint backfill, but the MDBX
COW metric is emitted by Erigon and remains high independently of that CL I/O.
During longer observation periods:
mdbx.datremained approximately6.26 GiB;db_size{db="chaindata"}remained constant;ReclaimableSpace,CommitmentVals, andChangeSets3changed in bothdirections instead of growing without bound;
db_rotx_overloaded_totalremained0;--externalcland no CL input reduced physical writes tothe host background level while the execution head remained static.
This looks like sustained MDBX COW/page-split churn caused by per-block
execution state and commitment updates rather than database growth, Caplin,
pruning backlog, or RPC traffic.
Steps to reproduce the behaviour
eth_syncing=falseandzero public-head lag.
by the number of processed blocks.
when execution is intentionally held static with
--externalcland no CL.For a control that isolates consensus input, start Erigon with
--externalcland no CL. MDBX COW remains zero while the execution head is static. Then attach
a synced external CL: MDBX COW returns as execution resumes at chain tip.
Related work
This report may be an operator-visible measurement of the work already tracked
in:
trie writes to reduce MDBX write amplification;
to large randomly keyed Commitment values and proposes a sequential value
layout.
Could you confirm whether
110-140 MiBof MDBX COW per mainnet block isexpected on 3.5.4 and whether these two changes are intended to address this
steady-state write volume? I can provide raw Prometheus series, a longer test
window, selected Erigon logs, or test a specific branch/build if useful.
Backtrace
There is no crash or backtrace. Erigon remains synced, has no automatic
restarts, and logs no errors during the measurement windows.