Plan disk for an xOne node in three steps. Pick the sync mode and read its measured datadir size. Size the filesystem so that free space stays above the 15% alert line. Then learn what the node does at its own lines: stop import at 2% free, resume at 3%, exit at 1%.

No xOne repository publishes a disk recommendation. The hardware and disk post lists the limits. The storage layout post explains the files. The xOneTS, xOnePy and xOneC repositories are private.

Which two disk lines does an xOne node have?

The node has its own watermark, and Prometheus has a separate alert. The alert fires first, at less than 15% free. The node stops import at 2% or 2 GiB free.

REFERENCE TABLEScroll to explore all columns →
Line Free space Effect
Alert XoneDiskAlmostFull below 15% for 10 minutes Warning. You act.
Alert XoneDiskCapacityUnknown no datadir filesystem series for 10 minutes Warning. node_exporter is down or the regex matches nothing.
Resume above 3% or 3 GiB Import runs again (disk_ok).
Stop below 2% or 2 GiB Import stops at a block boundary (disk_low).
Exit below 1% or 1 GiB, two samples in a row Clean stop, exit code 4 (disk_full).

Each node line is the larger of its percent and its byte floor. The node samples the datadir filesystem every 5 seconds with df -P -k. The first sample runs before any writer starts. The defaults are in config.rs and diskguard.rs. The alerts are in alerts.yml.

ADR-007 is still proposed. It proposes higher lines than the code uses. For alert setup, see node monitoring.

How much free space does the filesystem need?

Size the filesystem so that the datadir plus planned growth fills at most 85% of it. Then free space stays above the 15% alert line. The alert line sits well above the node lines.

This is arithmetic on the lines above, not a recommendation:

REFERENCE TABLEScroll to explore all columns →
Filesystem Stop Resume Exit Alert (15%)
1 TiB 20.48 GiB 30.72 GiB 10.24 GiB 153.6 GiB

On a filesystem below 100 GiB the byte floors win. Above it the percents win. Minimum filesystem size = (datadir + growth) / 0.85.

Example. The net2040 archive datadir was 22.78 GB at the sample below. Growth was about 410 MB per 100,000 blocks over a range of mostly empty blocks, so 4.1 GB for 1,000,000 blocks. Then (22.78 + 4.1) / 0.85 = 31.6 GB. Dense blocks cost more: measure your own rate.

How big is the datadir in each sync mode?

Snap and minimal datadirs were 0.09 to 0.15 GB on net2040. Full and archive datadirs were 17.99 to 22.78 GB. On Apothem the xOne snap datadirs were 31.12 to 75.11 GB.

Source: xOne team measurement, 2026-11-14 19:20 UTC, one sample. The method was du -sx --block-size=1 on the datadir, shown here in decimal GB. The reference head was 841,381 on net2040 and 85,385,427 on Apothem.

REFERENCE TABLEScroll to explore all columns →
Network Client and mode Datadir
net2040 xOneRS full 20.64 GB
net2040 xOneRS archive 22.78 GB
net2040 xOneRS fast, minimal 0.15 GB each
net2040 xOneTS full 19.56 GB
net2040 xOneC full, archive 17.99 GB, 22.22 GB
net2040 xOneC snap, minimal 0.14 GB each
net2040 xOnePy snap, minimal 0.09 GB each
Apothem xOneRS snap 75.11 GB
Apothem xOnePy snap 31.12 GB
Apothem xOneC snap 51.05 GB

The two xOneRS Apothem nodes are different nodes and builds. Do not average them. Until you have your own number, plan Apothem at the largest value. For the modes, see archive mode.

How fast does an xOne datadir grow?

Main has one growth record: the net2040 archive run in docs/ops/archive.md. It has no Apothem growth rate and no per-day figure.

REFERENCE TABLEScroll to explore all columns →
Range (sampled every 5 minutes, 2026-11-14) chain.mdbx Whole datadir
0 to 215k (blocks of 20,000+ transactions up to ~50k) 4.56 GB 20.3 GB
215k to 793k (mostly empty blocks) +0.47 GB, about 81 MB per 100k blocks +2.38 GB, about 410 MB per 100k blocks
at 832,598 5.03 GB 22.8 GB

ADR-007 still asks for the daily growth before its disk values are final (question 3). To get yours, read the datadir size and the head block twice, hours apart:

du -sx --block-size=1 <datadir>
curl -s -H 'content-type: application/json' \
  --data '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' <rpc-url>

The size change divided by the block change gives bytes per block. Repeat it in a quiet range and a busy range.

What do segment files and the MDBX map limit?

Segment files hold headers, bodies and receipts, one file per 100,000 blocks. --datadir.ancient <path> moves them to another disk. --db.max-size (default 1TB) caps the MDBX map, and --db.growth-step (default 64MB) sets its growth step.

  • Segments: the directories are static/headers, static/bodies and static/receipts. The path is recorded in the datadir. A wrong or missing path refuses to start (flags.md).
  • Second disk: the disk guard receives the datadir path only, so it does not sample a separate segment disk. Extend the mountpoint regex in prometheus.yml so it labels both filesystems datadir="true".
  • MDBX: the bounds are 16MB to 8TB. Startup refuses an existing mdbx.dat larger than --db.max-size. A full map fails the write with an error that names the flag. Committed data stays intact. Restart with a larger value (db-geometry.md).

What do I do at each line?

Act at the alert, before the stop line. At disk_low, free space and the node resumes alone. At disk_full, free space and restart.

  1. XoneDiskAlmostFull: grow the filesystem or free space on it. xone doctor warns below the resume line and fails below the stop line.
  2. XoneDiskCapacityUnknown: check the node job and its mountpoint regex in prometheus.yml.
  3. disk_low: import has stopped and the producer refuses to seal ("disk low: block production paused"). RPC reads, serving and consensus timers continue. A validator cannot vote on blocks it lacks, so treat it as a "not producing" alarm. The log shows disk_ok above the resume line.
  4. disk_full: the node stopped with exit code 4. Free space, run xone doctor, start again.

To move the lines, set the six limits.disk_{stop,resume,exit}_{pct,min_bytes} keys. Keep exit < stop < resume. A misordered set refuses to start. Example values only:

[limits]
disk_exit_pct = 3
disk_stop_pct = 5
disk_resume_pct = 7

How do other clients handle disk limits?

Geth also moves history files to another disk. Nethermind documents a low-disk shutdown threshold. The table compares features, not sizes.

REFERENCE TABLEScroll to explore all columns →
Client What its documentation says xOne
geth The freezer moves with --datadir.ancient, as stated in Geth databases. --datadir.ancient moves static/.
nethermind A low-disk shutdown threshold (LowStorageSpaceShutdownThreshold), as stated in the health check docs, no date listed. Exit at 1% or 1 GiB free, code 4.

Correction

On 2026-11-15 we removed an Apothem row that was labelled "xOneRS snap (second node)". That node reports the version xOne/v1.1.0/linux-amd64/go1.25.0: it runs xOneGo, the earlier Go line, not xOneRS. The other rows are unchanged.

Frequently asked questions

How much disk does an xOne node need?

No xOne repository publishes a figure. One sample measured 20.64 GB for an xOneRS full node on net2040 and 0.15 GB in fast or minimal mode. Size the filesystem so that datadir plus growth fills at most 85%.

When does an xOne node stop importing blocks?

It stops below 2% or 2 GiB free, whichever is larger. It exits with code 4 below 1% or 1 GiB.

Can I put xOne segment files on another disk?

Yes. Use --datadir.ancient <path>. The node's own watermark does not sample that disk, so alert on it too.

Sources