Skip to main content

Backup and restore

AutoAir's data lives in three places. Back up all three, with the same schedule and retention:

WhatWhereWhy it matters
DAGsThe deploy target: a local folder, object storage, or a git repositoryThe specs (<dag_id>.autoair.json), generated DAG files and version history. This is what Airflow runs
AutoAir stateThe state store: files under <state> or a SQLite/PostgreSQL databaseTemplates, audit trail, reviews and proposals, AI memory, AI audit, AI rules, MCP servers, icons, the UI-chosen deploy target, users seen
Keys and configurationYour secret store and configuration managementEncryption and signing keys, credentials, settings. Without the encryption key, stored secrets cannot be decrypted

<state> is <dags_folder>/<subfolder>/.autoair/ unless individual stores were moved with *_url settings; see Database.

Deploy target​

TargetWhat to back upNotes
localThe whole output folder (<dags_folder>/<subfolder>/), including .autoair/history/ (version snapshots) and .autoair/state/ (hashes of generated files).autoair/history/ is what the Versions panel shows. If the state store is also on the file backend, the same folder holds <state> (see below), so one backup covers both
objectThe bucket prefix (storage.object_url)Enable bucket versioning; it doubles as point-in-time recovery
gitThe repository, including branches autoair/* with open pull requestsThe git host is the source of truth and usually already backed up. History is the commit log. Back up the clone cache (storage.git.cache_dir) only if you want faster start-up

team_storage targets are separate deploy targets: back up each one.

State store​

File backend​

Back up <state> and every location you moved with a *_url setting:

Path (default)Content
templates/Saved templates (templates_url)
audit/Audit trail, JSON lines per day and process (audit_url)
proposals/Deploy proposals and reviews (iam.proposals_url)
icons/Custom icons and assignments.json (icons_url)
users/Users seen (admin panel)
deploy-target.jsonThe deploy target chosen in the UI (no secrets)
ai-audit/, ai-memory/, ai-knowledge/, ai-users/, ai-threads/, ai-rules/, ai-mcp-servers/, ai-troubleshoot/AI stores
collab.keyCo-editing ticket key (only when neither collab_secret nor Airflow's jwt_secret is set)
ai-user-llm.keyFernet key for per-user AI keys and MCP server headers (only when ai.user_llm.encryption_key is unset)

The files are written atomically one by one, so a file-level copy taken while AutoAir runs is consistent per file. For a consistent snapshot across files, use a volume or file-system snapshot, or stop writes briefly. Caches (ai-research-cache/, cache_dir) do not need a backup.

SQLite​

Back up the database file (default <state>/autoair.db) with SQLite's online backup, not a plain copy of a file that is being written (the WAL journal holds recent changes):

sqlite3 /opt/airflow/dags/autoair/.autoair/autoair.db ".backup '/backup/autoair-$(date +%F).db'"

PostgreSQL​

Back up the AutoAir schema or tables with your usual PostgreSQL tooling (base backups and WAL archiving, or logical dumps):

# AUTOAIR_DATABASE__URL is a SQLAlchemy URL (postgresql+psycopg://...); the PostgreSQL tools
# need the plain postgresql:// form. A password set separately (AUTOAIR_DATABASE__PASSWORD)
# goes into PGPASSWORD.
export PG_URL="${AUTOAIR_DATABASE__URL/postgresql+psycopg:/postgresql:}"
export PGPASSWORD="$AUTOAIR_DATABASE__PASSWORD" # only when the URL has no password

# everything AutoAir owns, when it has its own schema (database.schema_name=autoair)
pg_dump --format=custom --schema=autoair --file=autoair-$(date +%F).dump "$PG_URL"

# when it shares a schema, select its tables by prefix (database.table_prefix=autoair_)
pg_dump --format=custom --table='autoair_*' --file=autoair-$(date +%F).dump "$PG_URL"

Include <prefix>schema_version: it records which migrations were applied. The documents table's secrets collection holds keys generated by AutoAir (co-editing ticket key, the Fernet key when none is configured), so the database backup contains them; protect it like a secret.

Keys and configuration​

Back up, in your secret store:

  • AUTOAIR_AI__USER_LLM__ENCRYPTION_KEY (or the generated key: ai-user-llm.key on the file backend, the database's secrets collection on SQL). Without it, per-user AI keys and MCP server headers stored in the admin panel cannot be decrypted; users must re-enter them and admins must re-enter the headers.
  • AUTOAIR_COLLAB_SECRET (losing it only invalidates open co-editing tickets for up to collab_ticket_ttl).
  • AUTOAIR_AI__SERVICE__SHARED_SECRET, git tokens or GitHub App keys, AUTOAIR_DATABASE__PASSWORD, TLS certificates and keys, the marketplace signing key (autoair marketplace keygen output).
  • Your configuration files and environment (autoair config show --changed prints what differs from the defaults, with secrets masked; keep it with each backup for reference).

Airflow-side items AutoAir relies on (connections such as storage.git.conn_id, per-user git_<username> connections, FAB roles created by autoair iam sync-fab) are backed up with Airflow's metadata database.

Restore​

  1. Stop AutoAir (all replicas), or scale it to zero, so nothing writes during the restore.
  2. Restore the deploy target: the output folder, the bucket prefix, or the git repository. For git, open pull requests on autoair/* branches come back with the repository.
  3. Restore the state store:
    • file backend: copy <state> (and moved *_url locations) back, preserving file modes (collab.key is 0600);
    • SQLite: copy the backup file to database.url (or <state>/autoair.db);
    • PostgreSQL: pg_restore --clean --if-exists --dbname="$PG_URL" autoair-<date>.dump (PG_URL and PGPASSWORD as for the backup) into the same schema and table prefix.
  4. Restore keys and configuration: the same ai.user_llm.encryption_key, collab_secret, shared secrets and settings as at backup time.
  5. Check the schema (SQL backends): autoair db current. If you restored a backup taken before an upgrade and now run a newer AutoAir, apply migrations with autoair db upgrade (or let migrate_on_start do it). Restoring a database taken from a newer AutoAir into an older one is not supported: restore the matching version.
  6. Start AutoAir and verify.

Verify​

CheckHow
Server healthyGET /api/ready answers 200; the storage check is ok
Schema currentautoair db current shows no pending migrations; admin panel Database tab shows Up to date and plausible row counts
DAGs presentThe builder's DAG list shows the expected DAGs; open one and check its Versions history
TemplatesThe templates gallery and the admin panel's Templates tab list saved templates
Audit trailThe admin panel's Audit tab shows records up to the backup time
ApprovalsThe Approvals tab shows pending proposals (proposals older than iam.proposal_ttl_seconds are discarded)
Deploy targetThe admin panel's Overview shows the expected deploy target and its source (settings or ui)
Encrypted dataA user with a personal AI model can still use it; MCP servers in the admin panel pass Test connection
End to endValidate and deploy a test DAG to a non-production environment

Practise the restore regularly on a staging deployment; an untested backup is not a backup.

See also Database, Scaling and Upgrading.