An archive node keeps the state of every block from genesis. A full node keeps a recent window only. This post says which reads need an archive node, how xOne stores the history, and where each client stands today.
What an archive node does
A full node answers state reads inside its state window. Below the window it refuses the read with a typed unsupported history error. An archive node answers at any canonical block.
These reads need the historical state (xOneRS archive guide):
eth_getBalanceeth_getTransactionCounteth_getCodeeth_getStorageAteth_call
Explorers, indexers and audit tools use these reads on old blocks.
How xOne stores the history
The four clients use the same core design. Each block also writes two history tables:
AccountHistory: the hashed address, then the block number. The value is the account record before the block.StorageHistory: the hashed address, the hashed slot, then the block number. The value is the slot word before the block.
To read key k at block n, the node seeks the first history row of k above n. That row holds the value after n. If no such row exists, k has not changed since n, and the head state holds the value. One cursor seek answers one key. An unwind deletes the history rows of the blocks it removes.
In xOneRS the history rows are written in the same MDBX transaction as the block. The per-block changesets that unwind uses keep their window. Only the history rows are never pruned (changesets spec).
Start an archive node
In xOneRS, start on an empty datadir with full sync:
xone --network net2040 --datadir <empty dir> --gcmode archive --syncmode full ...
The same rules apply in the four clients:
--gcmode archiveneeds an empty datadir. The datadir keeps its mode afterwards.- A datadir written in the other mode refuses to start. In xOneRS the error names the stored mode.
--gcmode archivewith--syncmode snapor--minimalis refused. xOneRS, xOneTS and xOnePy also refusefast. A snapshot has no history below its anchor.- The ethstats board shows
gcMode: archive.
The flag is documented in the flag reference. It follows the geth-XDC flag name.
Status per client
Status is from main and from the net2040 tracker comment of 2026-11-14T18:30Z (xOneRS#140). The xOneTS, xOnePy and xOneC repositories are private.
| Client | Archive code on main | Archive node on net2040 |
|---|---|---|
| xOneRS | Merged in PR #416 on 2026-11-14. #152 is closed. | Full sync from genesis to block 832,598 on 2026-11-14. 378 of 378 reads equal to the geth-XDC archive (PR #416). |
| xOneTS | Merged in PR #89 on 2026-11-13. #74 is closed. | 130 of 130 reads equal at blocks 0, 1, 16, 16,000 and 18,000. The tracker lists the node as syncing from genesis, at block 184,398 of tip 840,762. |
| xOnePy | Merged in PR #95 on 2026-11-14. #85 is still open. | At the tip. 124 of 124 historical reads equal. Three of three seals on a borrowed seat. |
| xOneC | Merged in PR #80 on 2026-11-13. #61 is closed. | At the tip. 245 of 245 historical reads equal. Three of three seals on a borrowed seat. |
xOneTS has no archive node at the tip yet. Its sync-modes document lists the lag sample at the tip and the reads at later blocks as open (sync modes).
The 825,238 figure
The tracker row for the first Rust archive node says: state is retained from block 825,238 only, with no true state archive. PR #416 gives the same symptom before the change: eth_getBalance at block 16 answered unsupported history, with first retained block 825,238. The merged archive mode removes that limit. The tracker row has not been updated.
Growth
xOneRS measured the cost on net2040 (full sync to block 832,598, 2026-11-14):
chain.mdbx |
whole datadir | |
|---|---|---|
| Archive | 5.03 GB | 22.8 GB |
| Full node, same chain | 2.9 GB | 20.6 GB |
On net2040 the history costs about 2.1 GB, almost all of it from the dense range (blocks 0 to 215,000, with blocks of more than 20,000 transactions). The range from 215,000 to 793,000 is mostly empty blocks and adds about 81 MB of chain.mdbx per 100,000 blocks (archive guide).
Retention and the open gaps
spec/retention.md covers the other side: a node that starts from a snapshot at pivot P. It lists each rule that reads below a block and the longest lookback. The window is derived from the chain spec, not set as a constant. For Apothem at pivot 84,000,000 the header window is 4,500 blocks. The state window is the pivot itself.
An archive node needs no such window for state, because it holds every block. For that reason it syncs from genesis and cannot start from a snapshot.
These reads are not served from the history yet in xOneRS: eth_getProof below the window, snap/1 at old roots, and the tracers. In xOneTS and xOneC, snap/1 serves the roots of the last 4,096 blocks only, and historical eth_getProof is not served. In xOnePy, snap/1 serves any canonical root while the rebuilt state is at most 4,194,304 rows.
Sources
- xOneRS: docs/ops/archive.md, spec/retention.md, spec/state/changesets.md, docs/cli/flags.md, PR #416, issue #152, tracker #140
- xOneTS (private): docs/ops/net2040-ts-sync-modes.md, PR #89, issue #74
- xOnePy (private): docs/ops/net2040-py-sync-modes.md, PR #95, issue #85
- xOneC (private): docs/ops/net2040-node.md, PR #80, issue #61
This article describes the source and evidence at its review date. Check the linked repository for current implementation and qualification status.
Explore the engineering evidence