Snapshots
This page is for operators who create, verify, package, import, and inspect NOOSChain snapshot artifacts.
Use the focused pages for adjacent concerns:
| Need | Page |
|---|---|
| General snapshot model and conceptual recipes | General Snapshots |
| Choosing a recovery path and rejoining production | Backup, Restore, And Recovery |
| Snapshot format and implementation internals | Snapshot Internals |
| Production admission after restore | Production Readiness |
When To Use Snapshots
Use snapshots to:
- create a verified backup or bootstrap artifact;
- prove backup restore in
production backup-drill; - restore an observer or replacement database;
- bootstrap from a finalized checkpoint instead of replaying from genesis;
- package a chain state artifact for controlled movement between environments;
- support Raft follower catch-up through the same verified checkpoint model.
Snapshots are not a fork-choice rule, not a blind database copy, and not a replacement for role-specific recovery decisions.
Safety Rules
- Run export/import from a trusted operator environment with direct database access through
DATABASE_URL. - Verify every snapshot before moving it, storing it, or importing it.
- Use
consensus_state_onlyunless you explicitly need local ciphertext. - Treat
include_local_ciphertextarchives as sensitive operational artifacts. - Import into an empty database/schema for normal restore.
- Use operator restore only for deliberate disaster recovery.
- Do not return a restored node to production traffic until the recovery runbook and production preflight pass.
Snapshot export and import are intentionally not exposed through the Admin GUI or HTTP export APIs. Large exports can block the node web server, so operators run them as local jobs.
Export Modes
| Mode | Use when | Notes |
|---|---|---|
consensus_state_only | Default bootstrap, backup, recovery drill, and most restores. | Omits local ciphertext and marks payload availability unavailable in the artifact. |
include_local_ciphertext | Local recovery needs ciphertext already present on the exporting node. | Never includes plaintext or raw keys, but does include encrypted payload bytes where locally available. |
consensus_state_only is the safest default because ciphertext availability is local operational state, not consensus state.
Common Commands
Set DATABASE_URL to the database/schema you are exporting from or importing into:
$env:DATABASE_URL="postgres://user:password@127.0.0.1:5432/nooschain"List snapshot metadata:
npm run noos -- snapshots listExport the default packaged archive:
npm run noos -- snapshots export --output .\snapshot.noosnap.tar.gz --mode consensus_state_onlyVerify an archive:
npm run noos -- snapshots verify --file .\snapshot.noosnap.tar.gzImport into an empty database:
npm run noos -- snapshots import --file .\snapshot.noosnap.tar.gz --mode empty_database_only --yesDry-run an import:
npm run noos -- snapshots import --file .\snapshot.noosnap.tar.gz --mode empty_database_only --dry-runRecipe: Create And Verify A Backup Snapshot
Use this for a safe operator backup artifact.
- Set
DATABASE_URLto the source database. - Export in
consensus_state_onlymode. - Verify the exported archive.
- Store the artifact with your normal backup controls.
- Run a backup drill on the cadence required by production policy.
$env:DATABASE_URL="postgres://user:password@127.0.0.1:5432/nooschain"
npm run noos -- snapshots export --output .\node-backup.noosnap.tar.gz --mode consensus_state_only
npm run noos -- snapshots verify --file .\node-backup.noosnap.tar.gz
npm run noos -- production backup-drill --output .\backup-drillproduction backup-drill proves the artifact can restore into isolated schemas and pass verification. See Backup, Restore, And Recovery.
Recipe: Export With Local Ciphertext
Use this only when local recovery explicitly needs ciphertext already present on the exporting node.
npm run noos -- snapshots export --output .\snapshot-with-ciphertext.noosnap.tar.gz --mode include_local_ciphertext
npm run noos -- snapshots verify --file .\snapshot-with-ciphertext.noosnap.tar.gzThe artifact still does not contain plaintext, private keys, raw DEKs, or operator tokens. It can reveal encrypted payload bytes and local ciphertext availability, so handle it as sensitive operational data.
Recipe: Restore Into An Empty Database
Use this for normal observer restore, replacement database bootstrap, and most non-validator recovery.
- Stop the target node.
- Create or select an empty database/schema.
- Set
DATABASE_URLto the target. - Verify the archive.
- Import with
empty_database_only. - Run chain verification before restart.
- Follow the role-specific recovery runbook before production traffic.
$env:DATABASE_URL="postgres://user:password@127.0.0.1:5432/nooschain_restore"
npm run noos -- snapshots verify --file .\node-backup.noosnap.tar.gz
npm run noos -- snapshots import --file .\node-backup.noosnap.tar.gz --mode empty_database_only --yes
npm run verify:chainFor validators, do not stop here. Validator restore also depends on Raft data directory safety and runtime membership. Use Backup, Restore, And Recovery.
Operator Restore
operator_restore is a guarded disaster-recovery mode for intentionally replacing existing local database contents. It is disabled in production unless NOOSCHAIN_ALLOW_OPERATOR_RESTORE=true.
$env:NOOSCHAIN_ALLOW_OPERATOR_RESTORE="true"
npm run noos -- snapshots import --file .\backup.noosnap.tar.gz --operator-restore --yesBefore using it:
- stop the node and sidecars;
- take a filesystem/database backup of the current state;
- verify the snapshot archive;
- confirm the target role and recovery scenario;
- ensure no process is writing to the database;
- run chain and replay verification before restart.
Use this only with the recovery runbook.
Pack And Unpack
The default operator artifact is a packaged archive file, usually snapshot.noosnap.tar.gz.
Operators can also work with an unpacked .noosnap directory when a filesystem backup tool will handle packaging:
npm run noos -- snapshots export --format archive --output .\snapshot.noosnap --mode consensus_state_only
npm run noos -- snapshots pack --input .\snapshot.noosnap --output .\snapshot.noosnap.tar.gz
npm run noos -- snapshots unpack --file .\snapshot.noosnap.tar.gz --output .\snapshot.noosnapPackaging is a transport wrapper. Verification still checks the snapshot manifest, table content, hashes, references, and state root.
Legacy JSON snapshots are still available with explicit --format json, but they are intended for compatibility and debugging rather than large operational backups:
npm run noos -- snapshots export --format json --output .\legacy-snapshot.json --mode consensus_state_onlyProgress And JSON Output
Snapshot operations can run long enough that progress matters.
- Progress is written to stderr so JSON stdout remains machine-readable.
- Use
--no-progressto suppress progress. - In
--jsonmode progress is suppressed unless--progressis also passed. - Use
--dry-runto validate command shape and planned steps before writing files or importing rows.
Performance And Tuning
Default restore settings are conservative. Tune only after measuring on the target machine.
| Setting | Consider when |
|---|---|
NOOSCHAIN_SNAPSHOT_COPY_ENABLED=false | You need the conservative batched insert path instead of PostgreSQL COPY. |
NOOSCHAIN_SNAPSHOT_COPY_SCHEMA | The CLI connection's current_schema() is not the import target schema. |
NOOSCHAIN_SNAPSHOT_STREAM_BATCH_SIZE | Streaming batch size needs tuning for large imports. |
NOOSCHAIN_SNAPSHOT_STATE_LEAF_BATCH_SIZE | State-leaf materialization batch size needs tuning. |
NOOSCHAIN_SNAPSHOT_SMT_CACHE_MAX_ENTRIES | SMT rebuild cache size needs tuning. |
NOOSCHAIN_SNAPSHOT_REBUILD_RECORD_INDEXES_THRESHOLD | Large public-index imports should rebuild secondary indexes in bulk. |
NOOSCHAIN_SNAPSHOT_DROP_RECORD_INDEX_CONSTRAINTS=false | You prefer row-by-row constraint maintenance over faster bulk rebuild. |
NOOSCHAIN_SNAPSHOT_MAINTENANCE_WORK_MEM | PostgreSQL index rebuild memory needs tuning. |
NOOSCHAIN_SNAPSHOT_IMPORT_SYNCHRONOUS_COMMIT=off | The restore job can be rerun after a crash and accepts weaker commit durability during import. |
For capacity testing:
npm run benchmark:snapshotsUse benchmark output to decide whether bottlenecks are export, verification, PostgreSQL COPY, final index rebuild, or SMT materialization.
Raft InstallSnapshot Boundary
Raft follower catch-up uses the same verified checkpoint model, but operators normally do not invoke it directly. A Raft leader can send a snapshot when a follower is too far behind; the follower verifies the snapshot and records a checkpoint before applying later committed blocks.
For the general model, see General Snapshots. For implementation details, see Snapshot Internals.
Limitations
- Historical snapshot export is not implemented yet; export targets the latest finalized height.
- Snapshot import does not perform automatic reorg, fork repair, or pruning.
- Snapshot-only nodes cannot fully replay from genesis unless historical blocks are also available.
- Operator restore is intentionally guarded and must not be used as a routine import path.
- Raft snapshot transfer currently sends one full snapshot document. Chunking, compression, resumable transfer, and streaming transfer are future work.