Skip to main content
gaia v28.3.1 stores the block store and the application state in an embedded key value database. Two backends are compiled in: goleveldb, the default, and PebbleDB. You choose once, before the first sync, because the two write different file formats. A node changes backend only by restoring a data directory written with the other one. This page assumes a node from Join mainnet.

Which backends the binary has

This prints github.com/cometbft/cometbft-db@v1.0.4 and github.com/cockroachdb/pebble@v1.1.5. cometbft-db v1.0.4 registers the pebbledb backend unconditionally, so every v28.3.1 build has it, whichever install method you used. The --db_backend help text on gaiad start lists goleveldb | cleveldb | boltdb | rocksdb | badgerdb and omits pebbledb. The help string is stale, and the backend works. The gaiad prune --help output names the three app backends the Cosmos SDK side accepts: goleveldb, rocksdb, and pebbledb.

Two settings, one choice

CometBFT and the application open their stores separately, so there are two keys. They must match.
The db_backend key at the top of config.toml covers the CometBFT stores (blockstore.db, state.db, tx_index.db, evidence.db). The app-db-backend key in app.toml covers application.db. When it is empty the application falls back to db_backend, so setting both is redundant but safe. The -s flag is needed on the config.toml write, see Join mainnet. Then restore a PebbleDB snapshot from the Sync a node table, or state sync into an empty data directory.
The settings are read at startup only. Changing them on a node with existing data does not convert anything. The node fails to open its stores, or opens empty ones and refuses to sync. Set them first. Then put the matching data in place. Then start.

Tell which backend a data directory uses

Look at any store directory. The largest is data/application.db:
Both backends write CURRENT and MANIFEST-<number> files, so look past those. A PebbleDB directory has an OPTIONS-<number> file and stores tables as *.sst. A goleveldb directory stores tables as *.ldb and has no OPTIONS- file. A LOG file can appear in either directory (a goleveldb-configured open leaves one behind in a PebbleDB directory), so do not use it as the tell. A freshly created PebbleDB store on v28.3.1 contained 000002.log, CURRENT, LOCK, MANIFEST-000001, and OPTIONS-000003. A goleveldb store contained 000002.ldb, 000003.log, CURRENT, LOCK, LOG, and MANIFEST-000004. Run the same check on a downloaded archive before extracting it, as shown on Sync a node.

Why operators switch

PebbleDB is the backend that most of the current Hub snapshot providers who state a backend have moved to. It is also the one the Hub’s own infrastructure work focuses on. The practical differences operators report are shorter compaction pauses on large stores and steadier disk throughput. The disk ratio between the two was not measured for this page, so do not plan capacity on a claimed saving. If your node is healthy on goleveldb, there is no requirement to switch.

Switch an existing node

The only supported switch is to replace the data directory.
On a validator, keep data/priv_validator_state.json through the switch. It is the double sign guard. A reset replaces it with a fresh file at height 0. A restored archive replaces it with another node’s copy. Either one removes the guard.
  1. Stop the node and copy ~/.gaia/data/priv_validator_state.json somewhere safe.
  2. Set db_backend and app-db-backend to the target backend, as above.
  3. Reset the data directory with gaiad comet unsafe-reset-all --keep-addr-book.
  4. Restore a snapshot made with the target backend, or configure state sync, following Sync a node.
  5. Put priv_validator_state.json back and start the node.
A validator should do this on a sentry or a standby machine first, then swap, so it never misses blocks while a 15 GB archive downloads.

Prune offline

The gaiad prune command is meant to apply a pruning strategy to the application store while the node is stopped. On gaia v28.3.1 it does not work. Both prune default and prune custom, with or without --app-db-backend, panic before touching the store with panic: failed to read genesis from file <home>: is a directory. They panic because the prune command has no chain-id, and the gaia app falls back to reading the home directory as the genesis file. There is no workaround on this release. The --chain-id flag is not a prune flag, and GAIAD_CHAIN_ID is ignored. Should the command run at all, prune custom additionally requires --pruning-interval. Also, --app-db-backend must name your store because it assumes goleveldb otherwise. Control history with the pruning setting in app.toml instead. Let the running node prune:
This writes pruning in app.toml (default, nothing, everything, or custom with pruning-keep-recent and pruning-interval). It takes effect at the next start. To reclaim disk on a node that ran with nothing for a long time, restore a pruned snapshot as in Switch an existing node.

Verify

The two settings must name the same backend. The last command prints an OPTIONS- file for pebbledb or a .ldb file for goleveldb.

Next

Run gaiad as a service, or Sync a node to put data in place.