Firewood Database

Learn about Firewood, the compaction-less database optimized for efficiently storing Merkleized blockchain state.

Firewood is a purpose-built embedded key-value store optimized for storing recent Merkleized blockchain state. Unlike traditional blockchain storage approaches that layer Merkle tries on top of generic databases, Firewood stores trie nodes directly on disk, eliminating compaction overhead and enabling superior performance.

Summary

Firewood reimagines blockchain state storage with several key innovations:

  • Native trie storage: Stores Merkle trie nodes directly on disk
  • No compaction: Eliminates expensive compaction cycles
  • Recent state focus: Optimized for storing recent revisions
  • Disk-offset addressing: Root addresses are disk offsets, not hashes

Warning

Firewood is beta-level software. The Firewood API may change with little to no warning.

The Problem with Traditional Approaches

Most blockchain clients (including Ethereum's Geth and traditional AvalancheGo) store state using generic key-value databases like LevelDB or RocksDB. This creates a fundamental mismatch:

Problems with Generic KV Stores

IssueDescription
Double indexingTrie structure is flattened into KV pairs, then re-indexed by the database
Compaction overheadLSM-trees require periodic compaction that causes latency spikes
Write amplificationData is rewritten multiple times during compaction
Hash-based lookupFinding a node requires hashing, then database lookup

How Firewood Works

Firewood implements a Patricia trie (a specific variant of radix tree) natively on disk, using the trie structure itself as the index.

Native Trie Storage

Key design decisions:

  • Disk offset = address: A node's address is simply its offset in the database file
  • Direct pointers: Branch nodes point to disk offsets of child nodes
  • No hash lookup: Finding a node doesn't require computing or looking up hashes

Revision Management

Firewood implements a persistent (immutable) trie structure that supports multiple concurrent versions:

When state is updated:

  1. New versions of modified nodes are created
  2. Unchanged subtrees are shared between revisions
  3. Old revisions remain accessible for reads

Future-Delete Log (FDL)

Firewood tracks which nodes become obsolete:

This enables:

  • Predictable cleanup: No sudden compaction pauses
  • Inline compaction: Space is reclaimed as part of normal operation
  • Configurable history: Retain as many revisions as needed

Technical Architecture

Core Components

firewood/
├── firewood/       # Database core: revisions, proposals, proofs
├── storage/        # Node store, free lists, hashing
├── ffi/            # Go bindings (CGo)
├── fwdctl/         # Command-line tool
├── triehash/       # Ethereum trie hash helpers
└── benchmark/      # Benchmarks

Free Space Management

Firewood manages free space similarly to heap memory allocation:

When allocating space for new nodes:

  1. Check free lists for appropriate size
  2. If no suitable free space, allocate from end of file
  3. When revisions expire, return space to free lists

Key Features

Concurrent Access

Firewood efficiently synchronizes between:

ActorRole
Writer (Execution)Single writer commits new state
Readers (Consensus, RPC)Multiple readers access historical state

The persistent trie structure ensures:

  • Readers always see consistent state
  • Writes are atomic from readers' perspective
  • No locks required for read operations

Sequential Writes

Firewood allocates space for a new node from the free list of the matching size. If no free slot fits, it appends the node at the end of the file:

StateSlot 1Slot 2Slot 3Slot 4Slot 5
BeforeNode ANode BNode CFreeFree
AfterNode ANode BNode CNode DNode E

Benefits for SSDs:

  • Entire blocks are filled before moving to the next
  • Simplified garbage collection
  • Reduced write amplification
  • Increased SSD longevity

Proofs and State Sync

Firewood natively supports proof generation:

Proof TypeDescription
Key ProofProves a key exists in a specific revision
Range ProofProves a range of keys with all values
Change ProofProves differences between two revisions

These proofs enable efficient state sync without trusting the source.

Ethereum Compatibility

By default, Firewood uses SHA256 hashing (compatible with MerkleDB). For Ethereum compatibility, enable the ethhash feature:

# Build with Ethereum-compatible hashing
cargo build --features ethhash

This changes:

  • Hashing algorithm: SHA256 → Keccak256
  • Account handling: Understands RLP-encoded accounts
  • Storage trie: Computes account storage roots correctly

Note

The ethhash feature has some performance overhead compared to the default configuration.

Performance Characteristics

Compared to LevelDB/RocksDB

MetricTraditionalFirewood
Write amplificationHigh (compaction)Low (no compaction)
Latency spikesPeriodic (compaction)Minimal
Iteration speedFastFast (native trie)
Proof generationRequires reconstructionNative support
Space efficiencyGood after compactionConfigurable

Location in AvalancheGo

Firewood stores its data in regular files. On the C-Chain, AvalancheGo puts the Firewood files in {chain-data-dir}/{blockchainID}/firewood. The default chain-data-dir is $HOME/.avalanchego/chainData.

Metrics

Firewood provides comprehensive Prometheus metrics:

# Revisions held in memory, and the configured limit
firewood_revisions_active
firewood_revisions_limit

# Revisions written to disk
firewood_commits_total

# Commit latency
firewood_proposal_commit_duration_seconds

# Space reused from free lists, appended at the end of the file, and freed
firewood_storage_bytes_reused_total
firewood_storage_bytes_appended_total
firewood_storage_bytes_freed_total

See METRICS.md for the complete metrics reference.

Command Line Interface

Firewood includes fwdctl for database operations:

# Create a new database
fwdctl create --db /data/firewood --node-hash-algorithm merkle-db

# Insert a key-value pair
fwdctl insert --db /data/firewood key1 value1

# Query data
fwdctl get --db /data/firewood key1

# Show the root hash
fwdctl root --db /data/firewood

Integration with AvalancheGo

Firewood stores the state trie of an EVM chain. It does not replace the node database. The node database (LevelDB or PebbleDB, set with --db-type) still stores blocks and other chain data. Select Firewood for each chain with the state-scheme option in the chain config.

Warning

Firewood is an EXPERIMENTAL state scheme. To use it on the C-Chain, set "state-scheme": "firewood" in {chain-config-dir}/C/config.json. A Firewood C-Chain node cannot state sync. On Mainnet and Fuji, also set "state-sync-enabled": false, or the node shuts down with a FATAL error. The node then bootstraps by executing every block from genesis. AvalancheGo uses the Go bindings from firewood-go-ethhash.

Is this guide helpful?