Persistence

Sagewai persists all state across restarts with zero configuration. A fresh pip install sagewai + sagewai admin serve is already durable — no database to provision, no environment variables to set.


How it works by default

On first start Sagewai creates a home directory at ~/.sagewai (overridable via SAGEWAI_HOME) and writes all state there. Everything lives in three subdirectories:

DirectoryContentsDurable?
config/admin-state.json, connections.jsonYes — atomic JSON writes
db/sagewai.db — SQLite databaseYes — WAL mode
data/blueprint cache, worker scratch, artifactsYes — filesystem
secrets/master.key, profiles.jsonYes — mode 0700

The secrets/ directory is created with permissions 0700 so only the owning user can read it.


What persists where

SQLite (db/sagewai.db)

The store layer is built on SQLAlchemy Core and runs on SQLite by default. The following are durable across restarts:

  • Agent sessions and multi-turn conversation state
  • Workflow checkpoints and run history
  • Analytics data and per-model cost records
  • Saved workflow definitions
  • All other runtime stores in the sagewai.stores layer

JSON state file (config/admin-state.json)

Org and admin configuration that changes infrequently is stored as a human-readable JSON file with atomic writes (write-to-temp + rename). This includes:

  • Org settings and admin account config
  • Projects and project settings
  • Provider configurations
  • Playground agent definitions
  • Budget and guardrail configs
  • Saved-workflow definitions (metadata layer)

Connections (config/connections.json)

All connection records (HTTP, gRPC, MQTT, WebSocket, etc.) defined via the Connections Platform are stored here in human-readable form. Credentials are encrypted; the file itself is safe to back up.

sqlite-vec learnings (db/sagewai.db)

Vector memory — GlobalMemory learnings and per-agent vector memory — is stored as embeddings inside the same sagewai.db file using the sqlite-vec extension. If the extension is not available on your platform, Sagewai falls back to an in-process store automatically and emits a warning.


SAGEWAI_HOME layout

~/.sagewai/              ← SAGEWAI_HOME (default)
├── config/
│   ├── admin-state.json   org/admin config, projects, providers, budgets
│   └── connections.json   connection records (credentials encrypted)
├── db/
│   └── sagewai.db         SQLite: sessions, runs, workflows, analytics, vectors
├── data/
│   ├── blueprints/        Autopilot blueprint cache
│   ├── scratch/           worker scratch space
│   └── artifacts/         run artifacts
└── secrets/               (mode 0700)
    ├── master.key         Fernet master key
    └── profiles.json      Sealed identity profiles (encrypted)

Override the base directory:

export SAGEWAI_HOME=/var/lib/sagewai   # for a system-wide or container deployment
sagewai admin serve

Migrating from an older flat-file layout

Earlier versions wrote some files directly under ~/.sagewai/ (a flat layout) instead of the config/ and secrets/ subfolders. This migration is automatic — the first time sagewai admin serve starts, it relocates any legacy flat files (admin-state.json, connections.jsonconfig/; master.key, profiles.jsonsecrets/) into the canonical layout. The migration is idempotent (it skips files already in place) and never overwrites a newer file, so there is nothing to run by hand.


Upgrading to Postgres

SQLite is appropriate for a single-process deployment running on one machine. Use Postgres when you need:

  • Multi-process / horizontal scaling — multiple workers or admin servers sharing state
  • Larger datasets — thousands of concurrent sessions or millions of stored embeddings
  • Managed backups and replication — your existing Postgres infrastructure

Set SAGEWAI_DATABASE_URL and install the [postgres] extra:

pip install 'sagewai[postgres]'
export SAGEWAI_DATABASE_URL=postgresql://user:pass@host:5432/sagewai
sagewai db upgrade head   # apply the Alembic migrations to create the schema
sagewai admin serve

The [postgres] extra adds asyncpg (the async Postgres driver) and alembic (the migration tool). The same SQLAlchemy Core store layer that runs on SQLite runs unchanged on Postgres — there is no code-path difference; only the engine changes.

Moving existing SQLite data to Postgres

There is no automated SQLite → Postgres data-copy command today. Setting SAGEWAI_DATABASE_URL and running sagewai db upgrade head gives you a fresh Postgres schema; existing rows in your local sagewai.db are not carried over. Treat the Postgres switch as a clean start (or migrate data yourself with a tool such as pgloader). Keep the SQLite file as a backup either way.


Durability matrix

DataDefault backendDurable by defaultSurvives container restart?
Sessions + runsSQLiteYesYes (if SAGEWAI_HOME is on a mounted volume)
Workflow checkpointsSQLiteYesYes
Analytics / costsSQLiteYesYes
Org config / projectsJSON fileYesYes
Connection recordsJSON fileYesYes
Sealed profilesJSON file (encrypted)YesYes
Vector learningssqlite-vec in SQLiteYesYes
Blueprint cacheFilesystem (data/)YesYes
Fleet registry / tasksIn-processNoNo — workers re-register on restart

Fleet registry — known limitation

Fleet worker registration and in-flight task state remain in-process in this release. Workers re-register with the admin server on startup, so a server restart does not lose workers permanently — they reconnect within one heartbeat interval. Durable Fleet persistence (surviving the admin server process) is deferred to a future release.

Admin UI — separate image

The admin web panel is a separate container image (ghcr.io/sagewai/admin) and is not part of the pip install sagewai package. It talks to the admin API over HTTP and has no separate state of its own — all state lives in the backend's SAGEWAI_HOME.


Container deployments

When running the backend as a container, mount SAGEWAI_HOME to a named volume so state survives container replacement:

# docker-compose.yml excerpt
services:
  backend:
    image: ghcr.io/sagewai/backend:latest
    environment:
      SAGEWAI_HOME: /var/lib/sagewai
    volumes:
      - sagewai-home:/var/lib/sagewai

volumes:
  sagewai-home:

If you use Postgres instead, you still need to persist SAGEWAI_HOME for the secrets/ and config/ directories — those are never stored in the database.


See also