Skip to main content
Giga SS Store is the next step in Sei’s storage evolution on top of SeiDB. It splits the hot EVM state into its own dedicated state-store (SS) database so the node can scale toward the ~150k TPS target throughput, and so non-EVM modules stop paying write amplification for EVM state. After migration the SS layer is repartitioned into two cooperating stores: Only the SS layer changes for this migration. SC layer config is untouched and memiavl remains the authoritative source for the app hash, so this is invisible to the network.
The SC-layer routing field sc-write-mode is emitted in the generated app.toml template under the [state-store] section. It defaults to memiavl_only, so leaving it at the default keeps the SC layer untouched for this migration.
  • sc-write-mode — write routing mode for EVM data in the SC layer. Valid values: memiavl_only, migrate_evm, evm_migrated, migrate_all_but_bank, all_migrated_but_bank, migrate_bank, flatkv_only, test_only_dual_write. An invalid value fails at config parse time with a clear error.
  • sc-keys-to-migrate-per-block — the number of keys migrated from memiavl to flatKV per block while in a migration mode. Defaults to 1024 and must be greater than 0; ignored outside of a migration mode.
The legacy sc-read-mode and sc-enable-lattice-hash fields have been removed. Read routing and lattice-hash participation are now derived automatically from the write mode and the on-disk migration state — an app.toml that still references either field is no longer valid.
The sc-write-mode / sc-read-mode fields above configure EVM routing in the legacy composite commit store and are distinct from the internal memiavl → flatKV migration state machine used when converting the SC layer’s state DB from memiavl to flatKV. That migration is driven by its own WriteMode enum inside the state-migration package, not by sc-write-mode. Node operators encounter these modes as the migration progresses through a linear sequence of on-disk migration versions:
TestOnlyDualWrite exists only to preserve parity with legacy composite-store dual-write tests and must never be deployed to production machines.
The appropriate router for a given WriteMode is constructed by the state-migration package’s BuildRouter entrypoint, which returns the steady-state or in-flight migration router for that mode. Router construction requires a non-nil memiavl handle for every mode except FlatKVOnly, and a non-nil flatKV handle for every mode except MemiavlOnly.

Offline FlatKV EVM import (MigrateEVM)

The seidb tool ships an offline import path that moves the evm/ module’s SC-layer data out of memiavl and into FlatKV without running the in-process migration state machine. This is the operational entrypoint for the MigrateEVM (V0 → V1) transition on a stopped node.
This is an offline operation. The node must be fully stopped before running the import — the tool opens both the memiavl and FlatKV directories directly and will conflict with a running seid.

Reading the latest memiavl version

Before importing, read the latest committed memiavl version from a stopped node’s data directory. In a multi-validator cluster, run this on every node and pick the minimum so the import height is uniform across the cluster:
copy
--data-dir may point at either the data/ directory or the Sei home directory; if the basename is data, its parent is treated as home. You can also pass --home <sei_home> instead.

Running the import

copy
The import resets FlatKV before loading the selected memiavl rows and refuses to overwrite committed FlatKV data unless --force is supplied. If an external error interrupts the import (context cancellation, exporter or translator failure), the import is aborted rather than finalized — FlatKV is left at its pre-import committed version, so the operation can be retried without --force.
The import must run at the memiavl latest version. Importing FlatKV at a height H lower than the latest memiavl version is rejected: on the next GIGA_STORAGE startup the composite commit store’s reconcileVersions step would silently roll memiavl back to H, truncating every cosmos block in (H, latest]. If you genuinely need a non-latest height, roll memiavl back to that height yourself first (for example with seid rollback), then re-run the import. The CLI deliberately does not roll memiavl back on your behalf. A height ahead of the latest memiavl version is likewise rejected.

Configuration constraints across the import boundary

The import moves only the SC-layer EVM data into FlatKV. When restarting the node after the import, two settings must stay off across the import boundary or the node will panic on startup:
  • evm-ss-split = false. SS history for EVM remains in the existing combined cosmos SS database; the import does not populate a separate EVM SS directory. Flipping evm-ss-split to true triggers the rootmulti startup panic “EVM SS directory … does not exist but Cosmos SS already has history”. Moving the SS layer to split mode is a separate state-sync workflow (see Step 2) and is out of scope for the offline SC import.
  • sc-enable-lattice-hash = false. Before the import the chain ran without FlatKV, so tendermint persisted app hashes computed from memiavl alone for every block up to the import height. Enabling the lattice hash now would fold the FlatKV LtHash into the app hash, and the replay check at startup would fail with “state.AppHash does not match AppHash after replay”. Note that dual_write does not require the lattice hash — only split_write does.
A production rollout coordinates these transitions via a chain upgrade at an agreed height rather than flipping them mid-life.
For the full operational failure-mode catalog and recovery/tooling roadmap for MigrateEVM, see sei-db/state_db/sc/migration/OPERATIONS.md in sei-chain.
This guide tracks the canonical procedure in docs/migration/giga_store_migration.md inside sei-chain. Open an issue there if anything here drifts.

Prerequisites

This migration is supported on RPC nodes only. Validator nodes and archive nodes are not supported by this flow yet — do not run it against either.
  • A seid build with the evm-ss-split flag wired in (Sei v6.5 or later). Older releases used per-key evm-ss-write-mode / evm-ss-read-mode toggles; if your app.toml still has those keys, upgrade seid before continuing.
  • sc-enable = true and ss-enable = true in app.toml. Both must stay enabled.
  • A trusted RPC endpoint to state-sync from (chain ID and trust-height source).
  • Disk headroom for two SS databases. The EVM split does not duplicate data, but during migration both the old and the new layouts may briefly coexist on disk.
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

  • EVM reads are served exclusively from a dedicated EVM SS database.
  • Non-EVM modules no longer pay write amplification for EVM state.
  • A backend change (PebbleDB ↔ RocksDB) can be combined with the same state sync, since ss-backend drives both the Cosmos SS MVCC DB and every EVM SS sub-DB.

What’s different about EVM SS

EVM SS is point-query only by design (Get / Has). Iteration is explicitly disabled on the EVM backend for performance: 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 the following settings in ~/.sei/config/app.toml:
copy
If you want to switch SS backend in the same step:
  • PebbleDB → RocksDB: set ss-backend = "rocksdb", build seid with -tags rocksdbBackend, and install RocksDB per the RocksDB Backend Guide. ss-backend drives both the Cosmos SS MVCC DB and every EVM SS sub-DB, so a single setting flips both.
  • No data migration tool is needed across backends — the state sync populates the new layout.

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 snapshots produced by either the old or new FlatKV module are accepted.
Both stores end up fully populated at the snapshot height, so the node can start serving reads immediately. The full state-sync flow is documented in the Statesync guide. The minimal shape for this migration:
copy
Make sure priv_validator_key.json is in safe storage before deleting it from the config directory. Loss of this key is unrecoverable for a validator and is not relevant to RPC-only nodes — but if you’re following this from the wrong checklist you’ll find out the hard way.

Step 3: Verify the new layout

Once the state sync completes and the node starts producing blocks, confirm 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 out of the new EVM SS backend:
copy
The response should contain a "result" field rather than an RPC error.

Safety checks

seid runs three DB-state checks at startup and refuses to launch if the EVM SS and Cosmos SS DBs are inconsistent. They specifically catch the footgun of flipping evm-ss-split from false to true without state syncing.
  1. EVM SS directory missing or empty (before the EVM SS is opened). When evm-ss-split = true, the composite state store refuses to proceed if Cosmos SS already has committed history but the EVM SS directory (data/evm_ss/ by default) does not exist or is empty. Failing before the sub-DBs are opened means a rejected config does not leave a confusing empty data/evm_ss/ behind.
  2. EVM SS DB empty post-open, pre-recovery. Belt-and-suspenders for (1) when the directory exists but its DBs are empty. The WAL only covers 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 fires, the correct fix is either (a) complete the state sync described above, or (b) set evm-ss-split = false and restart. If data/evm_ss/ is stale from a failed attempt, remove it before state syncing.

Receipt backend default

When Giga Storage is enabled (GIGA_STORAGE=true), the receipt backend now defaults to pebble. Previously the receipt backend was left unchanged and had to be set explicitly through the RECEIPT_BACKEND environment variable. This default is applied implicitly: enabling Giga Storage sets RECEIPT_BACKEND=pebble unless you have already provided an explicit value. To use a different receipt backend, set RECEIPT_BACKEND explicitly before starting the node — an explicit value always takes precedence over the pebble default.
copy

Rollback

To roll back:
  1. Set evm-ss-split = false in app.toml.
  2. Restart the node. The EVM SS DB under data/evm_ss/ is no longer opened but stays on disk until manually removed.
To fully reclaim the disk used by EVM SS, stop the node and delete data/evm_ss/ after reverting the setting.
Cleanly rolling back to evm-ss-split = false requires another state sync. Under evm-ss-split = true, EVM writes go only to the EVM SS DB, so Cosmos SS will not have those writes. Restarting with evm-ss-split = false stops opening the EVM SS DB, but EVM-state queries will miss anything written after the Giga state sync until you re-state-sync without the split.

FAQ

Where do the data files live after migrating?

New nodes use an organized subdirectory layout under data/. Existing nodes with data in the legacy flat layout keep using their legacy paths automatically (legacy takes precedence when present).
  • Cosmos SS data lives under data/state_store/cosmos/{backend} on new nodes (e.g. data/state_store/cosmos/pebbledb/ for the default pebbledb backend). Existing nodes with data under data/{backend} (e.g. data/pebbledb/) continue using that legacy path.
  • EVM SS data lives under data/state_store/evm/{backend} on new nodes (e.g. data/state_store/evm/pebbledb/). Existing nodes with data under data/evm_ss/ continue using that legacy path. The evm-db-directory config, when unset, defaults to data/state_store/evm/{backend}.
  • SC data (memiavl + FlatKV) is untouched by this migration; on new nodes it lives under data/state_commit/memiavl and data/state_commit/flatkv, with legacy data/committer.db and data/flatkv retained when present.

Does Giga SS Store change the app hash or consensus?

No. The SC layer is unchanged, so memiavl remains the authoritative source for the app hash. Giga SS Store is a per-node SS 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 cleanly rolling back requires another state sync — see the Rollback section above.

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

Because evm-ss-split = true 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 while the composite store refuses to fall back to Cosmos SS, which would translate into missing EVM state at query time. The safety checks above block this scenario at startup.

Does Giga SS Store support historical proofs?

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