Reducing Bitcoin Full Node Storage Without Consensus Changes

I just reran the storage accounting against the fully synced node today, at approximately block 962,055. One block arrived while the audit was running, so the record count moved underneath the snapshot slightly.

The entire BitcoinRocks datadir is currently 769.904 GB / 717.029 GiB apparent size (717.218 GiB actually allocated on disk).

That includes all three optional indexes I run:

  • txindex: 58.391 GiB
  • blockfilterindex: 12.228 GiB
  • coinstatsindex: 0.089 GiB

Those optional indexes total 70.707 GiB, so without them the base full-node datadir is about 693.983 GB / 646.322 GiB.

The main components are:

  • compressed blk*.dat: 537.005 GiB
  • rev*.dat: 98.763 GiB
  • chainstate: 10.396 GiB
  • blocks/index: 0.108 GiB

The block audit currently represents 708.572 GiB of logical raw block payload stored in 536.988 GiB, saving 171.584 GiB on block payload, or 24.215%.

If I add those saved bytes back to this exact datadir, the equivalent dataset with raw block records would be 888.613 GiB, so compression is currently reducing the whole datadir by 19.309%, even with undo data, chainstate, and optional indexes left untouched.

On the RAM side, some of that is deliberate. I made a conscious effort to safely make use of up to roughly 25% of available system RAM during IBD in pursuit of faster synchronization from Genesis. One recurring complaint from end users is essentially, “I don’t want to wait a week for Bitcoin to sync,” so reducing IBD time was one of the implementation goals rather than minimizing memory use at all costs.

On this particular machine, a full synchronization from Genesis reached mainnet in roughly 30 hours. The system remained responsive throughout IBD and was still perfectly usable for other work. Once IBD completed and the node settled into steady-state operation, its resource usage became practically unnoticeable to me, despite this being a machine I use fairly heavily.

That said, I would not treat that result as a definitive Bitcoin Core vs. BitcoinRocks performance comparison. A proper stock-Core-versus-BitcoinRocks benchmark would need to control hardware, configuration, cache allocation, enabled indexes, network conditions, and starting state. Ideally, I would also like to see those measurements independently reproduced by third parties before making strong claims about relative IBD speed, RAM use, or steady-state runtime performance.

For completeness, here is the terminal output from the accounting script:

Full BitcoinRocks storage audit
Data directory:               BitcoinRocks v31.1.1 Data Directory
Software profile:             BitcoinRocks v31.1.1
Database backend:             RocksDB
Block storage format:         ZSTD-compressed flat-file block records with raw fallback

Scanned 4,313/4,313 blk files; records=962,057

Block-file XOR:                    enabled
blk files:                         4,313
block records:                     962,057
ZSTD-compressed block records:     857,601
Raw fallback block records:        104,456
Logical raw block payload:         760,823,248,710 B    760.823 GB    708.572 GiB
Stored block payload:              576,586,602,905 B    576.587 GB    536.988 GiB
Block payload saved:               184,236,645,805 B    184.237 GB    171.584 GiB
Payload reduction:                 24.215%
Eight-byte record headers:             7,696,456 B      0.008 GB      0.007 GiB
blk apparent file size:            576,604,250,024 B    576.604 GB    537.005 GiB
blk allocated disk blocks:         576,620,773,376 B    576.621 GB    537.020 GiB
Current blk prealloc/slack:             9,950,663 B      0.010 GB      0.009 GiB

ENTIRE DATADIR                     769,903,870,039 B    769.904 GB    717.029 GiB  allocated=717.218 GiB  files=10,645
blocks/ total                      682,765,926,391 B    682.766 GB    635.875 GiB  allocated=635.926 GiB  files=8,641
  blk*.dat                         576,604,250,024 B    576.604 GB    537.005 GiB  allocated=537.020 GiB  files=4,313
  rev*.dat                         106,046,158,393 B    106.046 GB     98.763 GiB  allocated=98.788 GiB   files=4,313
  blocks/index                         115,517,966 B      0.116 GB      0.108 GiB  allocated=0.118 GiB    files=13
chainstate                          11,162,232,953 B     11.162 GB     10.396 GiB  allocated=10.423 GiB   files=194
indexes/ total                      75,920,971,074 B     75.921 GB     70.707 GiB  allocated=70.818 GiB   files=1,798
  indexes/blockfilter               13,129,328,599 B     13.129 GB     12.228 GiB  allocated=12.269 GiB   files=792
  indexes/coinstatsindex                95,041,703 B      0.095 GB      0.089 GiB  allocated=0.101 GiB    files=14
  indexes/txindex                   62,696,600,772 B     62.697 GB     58.391 GiB  allocated=58.449 GiB   files=992

The script’s own estimate of the disk-space cost without block compression, which very closely matches what my Bitcoin Core v27.0 node with the same three optional indexes occupies on disk:

Current apparent datadir:          769,903,870,039 B    769.904 GB    717.029 GiB
Add back blk savings:              184,236,645,805 B    184.237 GB    171.584 GiB
Same datadir with raw blks:        954,140,515,844 B    954.141 GB    888.613 GiB
Net whole-datadir reduction:       19.309%
Everything except blk files:       193,299,620,015 B    193.300 GB    180.024 GiB

*edited for formatting

1 Like