Overview
Genesis on EKS stores all persistent state on a single PersistentVolumeClaim (genesis-data) backed by an EBS volume. Backing up Genesis means taking
periodic snapshots of that volume and preserving the Kubernetes Secret that
holds the master encryption key.
Genesis is a well-behaved StatefulSet tenant: one namespace, one PVC, standard
Kubernetes primitives. Any namespace-aware backup tool — Velero, AWS Backup for
EKS, Kasten K10, or manual EBS snapshots — works without application-level
changes.
The one wrinkle is SQLite consistency. Genesis uses multiple SQLite
databases in WAL mode, so a raw block-level snapshot of an active volume can
capture a mid-transaction state. A short pre-backup hook checkpoints the WAL
files to make the snapshot consistent.
Incremental object-store snapshots
For a portable snapshot of the Helm chart’s PVC layout, run the bundledexport-state command while the Genesis server is stopped:
gs:// bucket or a local directory, for example
/mnt/backups/<instance>. For an S3 destination, Genesis uses the ambient AWS
credential chain (pod identity, instance profile, AWS_PROFILE/SSO, or
AWS_* environment variables). For GCS, it uses the ambient Google identity.
The S3 region defaults to AWS_REGION, then AWS_DEFAULT_REGION, then
us-east-1; omit --kms-key-id to use the AWS-managed S3 key. GCS uses the
bucket’s default encryption and does not accept --kms-key-id.
To request the same snapshot from a running instance, use the authenticated
admin API instead of stopping the server manually. See the state snapshot
admin endpoints
for the request body, required permissions and example. The API validates the
S3 or GCS destination, returns 202 with a job ID, then pauses the instance
while the exporter copies its state and restarts the server. Poll the job after
the server is back to read the resulting snapshot ID. See State Snapshots and
Migration for GCS bucket
permissions, Workload Identity, and the API connection fields.
Each completed snapshot is stored below the destination in a new snapshot ID:
.microapp_venv/,
.microapp_home/, and __pycache__/; repository .git directories keep
their real name. Genesis refuses to export while its server is running: the
SQLite database is copied consistently, and stopping the server keeps the
directory trees consistent with that database.
Restoring an object-store snapshot
The Genesis Helm chart can restore a completed object-store snapshot into thegenesis-data PVC before the first Genesis container starts. Add the following
to your values file:
restore.from accepts either an s3:// or gs:// snapshot path, such as
s3://my-bucket/genesis-snapshots/<instance>/<snapshot-id>, or an instance
prefix, which selects its newest complete snapshot. The default is "", which
disables restore. restore.region defaults to "" and specifies the AWS
region for an S3 bucket; it is unused for GCS. restore.resources defaults to
{} and optionally sets the restore init container’s Kubernetes resource
requests and limits. For GCS, the init container reads with the pod’s Google
identity; see State Snapshots and Migration
for Workload Identity setup.
The restore init container uses the pod’s identity for object-store access,
including IRSA on EKS. It receives the master key from the same configuration
as the Genesis container: secrets.genesisMasterKey,
secrets.existingSecretGenesisMasterKey, or config.extraEnv.GENESIS_MASTER_KEY_REF.
The snapshot must use the same master key as the target instance. The restore
refuses a different key, an unsupported or newer release snapshot, an invalid
signature, any missing, extra, or corrupted file, and a database that fails
SQLite’s integrity check.
The chart requires an image that includes the restore runner. Release image
tags at or below v1.19.93 are rejected during chart rendering when
restore.from is set; use a newer image. A tag that is not a plain semantic
version is not ordered by the chart, so verify that it includes the restore
runner before deploying.
The init container only restores an empty volume. If the target already holds
Genesis state, it skips the restore on pod startup, including after a restart
or upgrade. Failures during discovery, verification, or staging leave the
existing volume unchanged, and the init container retries on the next pod
start. If a restart interrupts the final tree swap, the next init-container
run finishes that verified swap before Genesis starts. To restore again, use an
empty PVC, or stop Genesis and run the import runner with --force in a pod
that mounts the volume:
--runtime-root /app when the snapshot’s source paths were recorded under
a different runtime layout, such as a Snowflake SPCS migration. The restore
rewrites matching absolute paths as part of staging; see State Snapshots and
Migration for the path
rewrite behavior and migration workflow.
What lives on the PVC
Thegenesis-data PVC is mounted at four subpaths:
Everything stateful is on this single volume. The container image, ConfigMaps,
and environment variables are stateless and reconstructed from the Helm chart.
Backing up the master key
If you deploy with
config.extraEnv.GENESIS_MASTER_KEY_REF, the master key
already lives in AWS Secrets Manager or GCP Secret Manager. Ensure that
secret is included in your organization’s vault backup and rotation
policies — you do not need a separate Kubernetes Secret export.Secret):
If you use External Secrets (AWS Secrets Manager or GCP Secret Manager) for
connection credentials, those secrets survive independently of Genesis
backups. See External Secrets for details.
SQLite pre-backup hook
Genesis ships a checkpoint script atscripts/sqlite-checkpoint-hook.sh that
flushes all SQLite WAL files on the PVC before a snapshot. The script finds
every .db, .sqlite, and .sqlite3 file under /app/.genesis/db and
/app/bot_storage and runs PRAGMA wal_checkpoint(TRUNCATE) on each.
You can run it manually:
The checkpoint takes a few seconds at most. It does not stop the application
or interrupt running conversations. It flushes pending writes from WAL files
into the main database files so the on-disk state is self-consistent.
Backup tool setup
- Velero
- AWS Backup for EKS
- Manual EBS Snapshot
Prerequisites
- Velero installed in the cluster with the AWS plugin
- An S3 bucket for backup storage
- The EBS CSI driver installed (required for CSI snapshots)
Configure pod annotations
Add Velero backup hook annotations to your Helmvalues.yaml:Create a backup schedule
Manual backup
Restore
Recovery checklist
After restoring from any backup method:-
Verify the pod is running:
-
Check database integrity:
-
Verify the master key matches: If the Kubernetes Secret was also
restored, confirm it contains the correct
GENESIS_MASTER_KEY. If you useGENESIS_MASTER_KEY_REF, confirm the referenced AWS/GCP secret still exists and the pod’s IRSA/ADC identity can read it. If restoring into a new cluster, recreate the Secret orGENESIS_MASTER_KEY_REFconfiguration from your vault backup. -
Check the application health endpoint:
- Verify data: Log into the Genesis UI and confirm agents, threads, and connections are present.
Genesis includes automatic SQLite corruption detection and recovery
(
sqlite_recovery_core.py). If the database is slightly inconsistent after
a restore, Genesis will attempt to repair it on startup.RPO and RTO guidance
To reduce RPO impact:
- Blueprints and missions can be re-deployed from source control
- Connections require the master key; with it, they restore fully from the PVC backup
- External secrets (AWS Secrets Manager / GCP Secret Manager) survive independently
Supplemental: configuration export
genesis config export exports Genesis configuration to a YAML or JSON file
that can be version-controlled independently of PVC backups:

