Persistence
By default, all Simfra state lives in memory and is lost when the process exits. Setting SIMFRA_DATA_DIR enables write-through persistence to SQLite, so resources survive restarts.
Enabling Persistence
export SIMFRA_DATA_DIR=/var/lib/simfra
simfra
This creates:
$SIMFRA_DATA_DIR/simfra.db- SQLite database for resource metadata$SIMFRA_DATA_DIR/s3/- Filesystem storage for S3 object data$SIMFRA_DATA_DIR/bootstrap/- Terraform state when using Terraform bootstrap$SIMFRA_DATA_DIR/.master_key- Auto-generated encryption key (ifSIMFRA_PERSISTENCE_KEYis not set)
What Persists
Resource metadata and configuration are written to SQLite after every mutation:
- IAM users, groups, roles, policies, access keys, instance profiles
- EC2 VPCs, subnets, security groups, route tables, instances, volumes, AMIs, ENIs
- S3 buckets (metadata and policies; object data stored on the filesystem)
- SQS queues (configuration, attributes, tags - not messages)
- SNS topics, subscriptions, and platform applications
- DynamoDB tables, GSIs, and item data
- Lambda functions, layers, event source mappings
- KMS keys, aliases, and grants
- RDS instances, clusters, subnet groups, parameter groups
- EKS clusters, node groups, Fargate profiles, add-ons
- ELBv2 load balancers, target groups, listeners, rules
- CloudWatch alarms, metric streams, log groups
- EventBridge rules, targets, event buses
- Secrets Manager secrets and versions
- All other service resources with durable state
What Does NOT Persist
Transient runtime state is intentionally excluded:
- SQS messages - Messages in queues, in-flight state, delayed delivery timers
- FIFO dedup entries - 5-minute deduplication windows
- Data key caches - KMS envelope encryption data keys (regenerated on first use after restart)
- CloudWatch metric data points - Time-series data is ephemeral
- HTTP retry queues - Pending async deliveries (SNS, EventBridge targets)
- Docker container state - Containers are recreated from persisted resource metadata on startup
- STS session tokens - Temporary credentials are not persisted
Startup Behavior
On startup with SIMFRA_DATA_DIR set, Simfra:
- Opens
simfra.db(creates it if missing) - Loads all persisted resources into memory stores in dependency order (IAM first, then KMS, EC2, etc.)
- Reconciles Docker infrastructure (if
SIMFRA_DOCKER=true): recreates networks, DNS containers, and service containers from persisted metadata - Skips native bootstrap if persisted state was found (Terraform bootstrap always runs since Terraform state handles idempotency)
- Marks the health endpoint as ready
The server does not accept requests until loading is complete.
Encryption at Rest
Sensitive fields in the SQLite database (secrets, private keys, passwords) are encrypted with AES-256-GCM.
Auto-Generated Key
When SIMFRA_PERSISTENCE_KEY is not set, Simfra generates a random 32-byte key and stores it at $SIMFRA_DATA_DIR/.master_key. This is convenient for single-machine setups but means the key is stored alongside the data.
Explicit Key
For production or shared-storage deployments, provide your own key:
# Generate a 32-byte key
openssl rand -hex 32
# Set it as an environment variable
export SIMFRA_PERSISTENCE_KEY=a1b2c3d4e5f6... # 64 hex characters
The key must be exactly 64 hex characters (32 bytes). If the key changes or is lost, encrypted fields in the database become unreadable.
S3 Object Storage
S3 object data is stored on the filesystem under $SIMFRA_DATA_DIR/s3/, organized by bucket and key. Object metadata (ETags, content types, ACLs) is stored in SQLite alongside other resource metadata. This separation keeps the SQLite database small while supporting arbitrarily large objects.
Backup
To back up Simfra state:
- Stop Simfra (or accept a point-in-time snapshot)
- Copy
$SIMFRA_DATA_DIR/to your backup location - Include
simfra.db, thes3/directory, and.master_key(or record yourSIMFRA_PERSISTENCE_KEY)
The SQLite database uses WAL mode, so copying while Simfra is running produces a consistent snapshot as long as you copy both simfra.db and simfra.db-wal.