Skip to main content
Giga SS Store is the next step in Sei’s storage evolution, built on SeiDB. It splits the hot EVM state into a dedicated state-store (SS) database. The node can then scale toward the target throughput of approximately 150k TPS, and non-EVM modules stop paying write amplification for EVM state. After the migration, the SS layer is repartitioned into two cooperating stores: This migration changes only the SS layer. It does not change the SC layer or the app hash, so the change is invisible to the network.
This guide follows the canonical procedure in the sei-chain repository: docs/migration/giga_store_migration.md. If anything here drifts, open an issue there.

Prerequisites

Run this migration on RPC nodes only. This flow does not support validator nodes or archive nodes yet, so do not run it against either.
  • A seid build that supports the evm-ss-split flag (Sei v6.5 or later). Older releases used the per-key evm-ss-write-mode and evm-ss-read-mode toggles. If your app.toml still has those keys, upgrade seid before you continue.
  • sc-enable = true and ss-enable = true in app.toml. Both must stay enabled.
  • A trusted RPC endpoint for state sync (the chain ID and trust-height source).
  • Disk headroom for two SS databases. The EVM split does not duplicate data, but the old and new layouts may briefly coexist on disk during the migration.
The migration requires a full state sync. There is no in-place migration path and no live “dual-write then split” workflow. The state sync wipes the local data directory and imports a fresh snapshot into the new layout.

Benefits

  • The node serves EVM reads only from a dedicated EVM SS database.
  • Non-EVM modules no longer pay write amplification for EVM state.

What’s different about EVM SS

EVM SS is point-query only by design (Get and Has). For performance, iteration is explicitly disabled on the EVM backend. The hot EVM read path is tuned for direct key lookups, and cross-bucket scans would defeat the per-type sub-DB layout. Any EVM read that needs iteration must stay on the Cosmos SS side.

Migration steps

Step 1: Update app.toml

Apply these settings in ~/.sei/config/app.toml:
copy
Keep ss-backend = "pebbledb" during this migration. RocksDB support for the state store will be removed. No target release has been published. If the node already uses RocksDB, follow Move off RocksDB.

Step 2: State sync into the new layout

Giga SS Store is fully compatible with the existing state-snapshot format. On import, the composite state store routes each snapshot node based on the importing node’s evm-ss-split:
  • With evm-ss-split = true, EVM snapshot nodes go only into EVM SS, and non-EVM nodes go only into Cosmos SS.
  • The import path normalizes legacy evm_flatkv snapshot nodes to evm, so it accepts snapshots from either the old or the new FlatKV module.
Both stores are then fully populated at the snapshot height, so the node can serve reads immediately. The state sync guide documents the full flow. The minimal flow for this migration is:
copy
Make sure priv_validator_key.json is in safe storage before you delete it from the config directory. The loss of this key is unrecoverable for a validator but does not matter for RPC-only nodes. If you follow these steps from the wrong checklist, you can lose a validator key permanently.

Step 3: Verify the new layout

After the state sync completes and the node starts producing blocks, confirm that Giga SS Store is active in two places. Startup logs. All three lines should appear:
EVM RPC. debug_traceBlockByNumber is the cleanest end-to-end check. It forces the node to read EVM state from the new EVM SS backend:
copy
The response should contain a "result" field, not an RPC error.

Safety checks

seid runs three DB-state checks at startup and refuses to start if the EVM SS and Cosmos SS DBs are inconsistent. They specifically catch the mistake of flipping evm-ss-split from false to true without a state sync.
  1. EVM SS directory missing or empty (before the EVM SS is opened). This check applies when evm-ss-split = true. If Cosmos SS already has committed history but the configured EVM SS directory is missing or empty, the composite state store refuses to proceed. The check fails before the sub-DBs are opened, so a rejected config does not leave a confusing empty directory behind.
  2. EVM SS DB empty post-open, pre-recovery. This second safeguard for check 1 covers the case where the directory exists but its DBs are empty. The WAL covers only the last KeepRecent blocks, so replay cannot rebuild a fresh EVM SS from scratch.
  3. Mismatched earliest versions, post-recovery. If the two DBs were populated from different snapshots (or pruned independently), historical reads would be inconsistent. A non-zero earliest-version divergence aborts startup.
If any check fails, the correct fix is to either (a) complete the state sync described above or (b) set evm-ss-split = false and restart. If the configured EVM SS directory is stale from a failed attempt, remove it before the state sync.

Rollback

To roll back:
  1. Set evm-ss-split = false in app.toml.
  2. Restart the node. The EVM SS DB is no longer opened but stays on disk until you remove it.
To fully reclaim the disk used by EVM SS, revert the setting first. Then stop the node and delete the configured EVM SS directory.
To roll back cleanly to evm-ss-split = false, run another state sync. Under evm-ss-split = true, EVM writes go only to the EVM SS DB, so Cosmos SS does not have those writes. If you restart with evm-ss-split = false, the node stops opening the EVM SS DB. However, EVM-state queries miss anything written after the Giga state sync until you run state sync again without the split.

FlatKV EVM SC migration flow

Everything above concerns the SS (State Store) layer. The SC (State Commit) layer has a separate migration path. It moves the hot evm/ data out of memiavl and into FlatKV in place, without a state sync. Unlike the SS split, the SC migration changes how evm/ data contributes to the app hash. The contribution moves from the memiavl IAVL root to the FlatKV lattice hash. Every validator must therefore switch at the same block, or consensus halts.

How the migration starts

Since v6.7.0, governance controls the migration, and nodes follow it without config changes:
  • By default, every node runs in the auto write mode. The node derives its mode from the migration state on disk. It checks that sc-write-mode has a valid value, but it does not use the value.
  • The NumKeysToMigratePerBlock parameter in the migration params subspace sets how many keys move per block. The default, 0, keeps the migration paused. A ParameterChangeProposal can raise it to at most 1,000,000.
  • When the parameter becomes greater than 0, every auto node switches from memiavl_only to migrate_evm at the same height and starts to move keys. The node does not restart.
In v6.7, governance can start only the EVM migration. The later write modes (migrate_all_but_bank, all_migrated_but_bank, migrate_bank, and flatkv_only) exist, but no parameter starts them. During the migration, the node reads and iterates over both backends. The migration deletes a key from memiavl when it copies the key to FlatKV. If both backends report a key, the node uses the memiavl value. The migration boundary advances at most once per block. When the migration starts, the node stops serving state proofs for the evm store, because FlatKV has no proof builder. Proofs for other modules still work.

Pinning a write mode

To pin a write mode, set both keys in the [state-commit] section of app.toml. The generated app.toml does not include sc-write-mode-enable-auto, so add it yourself:
copy
A node whose history began in FlatKV, such as a node on a chain that started in FlatKV, must pin flatkv_only as shown above. In auto, such a node either fails every commit with a version-mismatch error or serves empty reads from memiavl.
A node pinned to memiavl_only does not take part in the migration. When governance starts the migration, the pinned node diverges from the network. Since v6.7.1, a node also refuses to start if a pinned evm_migrated, all_migrated_but_bank, or flatkv_only mode disagrees with the migration state on disk. The error starts with write mode is pinned to. The cosmos_only value from v6.4 and v6.5 app.toml files is still accepted as an alias for memiavl_only.

Write modes

For the local Docker devnet, GIGA_MIGRATE_FROM_MEMIAVL=true pins every node to memiavl_only (with sc-write-mode-enable-auto = false), the starting point of the devnet migration test. Do not set it together with GIGA_STORAGE. If you set both, GIGA_MIGRATE_FROM_MEMIAVL takes precedence.
copy

Checking migration status

The seidb migrate-evm-status subcommand reports the on-disk FlatKV EVM migrate state of a FlatKV directory as JSON. It clones the latest snapshot and WAL into a temporary directory before it reads. You can therefore run it against a live node’s data directory without contending for the FlatKV writer lock.
copy
--db-dir (short -d) points at the FlatKV data directory. --height selects a target version. The default, 0, selects the latest available version. The JSON includes migrate_evm_complete (true after the migration finishes), migration_version, version_at, and whether an in-flight boundary is still present. When the migration finishes, each node also emits a migration complete summary log line and seidb_migration_* OpenTelemetry counters for the migrated keys and bytes.

Importing EVM state from memIAVL into FlatKV

The seidb import-flatkv-from-memiavl command populates a FlatKV store from an existing memIAVL tree. It is for nodes that move to the FlatKV EVM commit store without a state sync. Two safety properties matter:
  • The import height must equal the latest memIAVL version. The command refuses a lower height, because the composite store’s version reconciliation would silently roll memIAVL back and truncate blocks. It also refuses a higher height. First, check the current version with seidb memiavl-latest-version. If needed, roll memIAVL back to the target height before you import.
  • Overwriting existing committed FlatKV data requires the explicit --force flag.
In the default auto write mode, the node does not use a FlatKV store that this command creates. The store has no migration metadata, so the node starts in memiavl_only.

FAQ

Where do the data files live after migrating?

  • Cosmos SS data uses data/pebbledb/ in the legacy layout and data/state_store/cosmos/pebbledb/ in the current layout.
  • EVM SS data uses data/evm_ss/ in the legacy layout and data/state_store/evm/pebbledb/ in the current layout.
  • Nodes created before the layout change keep their legacy paths automatically. A legacy directory takes precedence when it is present. New nodes use the current layout.
  • A non-empty ss-db-directory or evm-ss-db-directory overrides the corresponding default path.
  • This migration does not change SC data (memiavl and FlatKV).

Does Giga SS Store change the app hash or consensus?

No. Giga SS Store changes only the SS layer, which does not affect the app hash. It is a per-node change that is invisible to the network.

Can I migrate a validator node with this guide?

Not yet. This migration guide is for RPC nodes only.

Can I migrate an archive node with this guide?

Not yet. Archive-node migration is out of scope for this guide.

Can I toggle back to evm-ss-split = false after enabling it?

Yes, but a clean rollback requires another state sync. See the Rollback section above.

Why can’t I just flip evm-ss-split = true on a running node?

The evm-ss-split = true setting requires the EVM SS DB to already contain the full history that Cosmos SS has. A live flip would leave the EVM SS DB empty, and the composite store refuses to fall back to Cosmos SS. The result would be missing EVM state at query time. The safety checks above block this scenario at startup.

Does Giga SS Store support historical proofs?

No, and neither does SeiDB. SS stores raw KVs and does not reconstruct IAVL-style proofs.

Does enabling Giga Storage change the receipt backend?

In the localnode and rpcnode configuration scripts, setting GIGA_STORAGE=true defaults RECEIPT_BACKEND to pebble unless you set RECEIPT_BACKEND explicitly. To use a different value with Giga Storage, set the RECEIPT_BACKEND environment variable explicitly. The explicit value takes precedence over the default. The supported receipt-store backends are pebbledb (also called pebble) and littidx. For details on littidx, see the node operations guide. The former parquet option was removed. The node rejects an unsupported value for RECEIPT_BACKEND (or rs-backend in app.toml) with an error (unsupported receipt-store backend "parquet"; supported: pebbledb, littidx).