Skip to content

Backup & restore

NamiDB stores everything in the bucket — manifest, WAL, SSTs, schema. There is no external lock table, no separate metadata service, no per-tenant state living anywhere else.

Backup is aws s3 sync. Restore is aws s3 sync in the other direction.

Per-namespace backup

Terminal window
aws s3 sync \
s3://my-bucket/data/tenant-acme/ \
./backups/tenant-acme-2026-05-19/

Cross-region / cross-bucket replication

Terminal window
aws s3 sync \
s3://my-bucket/data/ \
s3://my-backup-bucket-dr/data/

You can do this online — readers and writers can be active during the sync. The worst case is that the backup captures a slightly older manifest version than what’s currently live. NamiDB’s snapshot semantics + epoch fencing guarantee the captured state is internally consistent.

Restore

To restore a snapshot to a fresh bucket:

Terminal window
aws s3 sync ./backups/tenant-acme-2026-05-19/ s3://my-new-bucket/data/tenant-acme/

Then open the namespace at the new URI. NamiDB reads the manifest and boots normally.

Migrating between backends

Same idea — sync between any two URIs:

Terminal window
# file:// → s3://
aws s3 sync /var/lib/namidb/prod/ s3://my-bucket/data/prod/
# s3:// → file://
aws s3 sync s3://my-bucket/data/prod/ /var/lib/namidb/prod/
# s3:// → gs:// (use gcloud rsync)
gsutil -m rsync -r s3://my-bucket/data/prod/ gs://my-bucket/data/prod/

After the sync, point your client at the new URI. The graph is the same.

What about in-flight writes during a restore?

Restoring while writers are active will fence them via epoch CAS — the manifest the writer is racing against gets overwritten, the writer’s next commit attempt returns 412 Precondition Failed, and the writer re-bootstraps. No corruption is possible because the manifest is the only authoritative root.

For a clean restore, stop writers, do the sync, then bring writers back up.

See also