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 (if SIMFRA_PERSISTENCE_KEY is 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:

  1. Opens simfra.db (creates it if missing)
  2. Loads all persisted resources into memory stores in dependency order (IAM first, then KMS, EC2, etc.)
  3. Reconciles Docker infrastructure (if SIMFRA_DOCKER=true): recreates networks, DNS containers, and service containers from persisted metadata
  4. Skips native bootstrap if persisted state was found (Terraform bootstrap always runs since Terraform state handles idempotency)
  5. 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:

  1. Stop Simfra (or accept a point-in-time snapshot)
  2. Copy $SIMFRA_DATA_DIR/ to your backup location
  3. Include simfra.db, the s3/ directory, and .master_key (or record your SIMFRA_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.