Backups & restore
Back up and restore the data stores behind a self-hosted instance
A self-hosted instance keeps state in a few stores: Postgres for application data, ClickHouse for the observability records (spans and traces), and MinIO for object storage. Redis is a cache (sessions, locks, rate limits, pub/sub), so it rebuilds on its own and doesn’t need a backup. RabbitMQ holds the task queue: losing it drops in-flight background jobs, so drain it before planned downtime rather than backing it up.
Postgres
Postgres holds the application data, so back it up on a schedule. Use the custom format, and pass -T so docker compose exec doesn’t allocate a TTY and mangle the binary dump:
# Backup
docker compose exec -T postgres \
pg_dump -U futureagi -d futureagi --format=custom \
> backup-$(date +%F).dump
# Restore
docker compose exec -T postgres \
pg_restore -U futureagi -d futureagi --clean --if-exists \
< backup-2026-04-22.dump
The named volumes that hold state. The compose project name is futureagi, so every volume is prefixed futureagi_:
| Volume | Holds |
|---|---|
futureagi_postgres-data | Postgres application data |
futureagi_clickhouse-data | ClickHouse spans and traces |
futureagi_minio-data | MinIO objects |
futureagi_rabbitmq-data | RabbitMQ task queue |
futureagi_redis-data | Redis cache (rebuildable) |
futureagi_peerdb-catalog-data | PeerDB replication catalog |
futureagi_peerdb-minio-data | PeerDB staging objects |
futureagi_fi-collector-data | fi-collector buffer |
ClickHouse
ClickHouse is not just a replica anymore. Since the CH25 cutover (CH25_DROP_LEGACY_CDC_CHAIN defaults to true), the fi-collector writes spans straight to ClickHouse and Django dual-writes traces. PeerDB only rebuilds the tables it mirrors from Postgres, so if you lose ClickHouse the observability data does not come back from a PeerDB re-init. Back it up on its own:
BACKUP DATABASE default TO S3('s3://your-bucket/ch-backup/', 'KEY', 'SECRET');
Warning
Don’t rely on PeerDB init to rebuild ClickHouse. It restores the mirrored Postgres tables, not the spans the collector writes directly. ClickHouse needs a real backup on its own schedule.
MinIO
Mirror the MinIO bucket to S3 with the MinIO client:
mc alias set local http://localhost:9005 futureagi <MINIO_ROOT_PASSWORD>
mc alias set s3 https://s3.amazonaws.com <AWS_KEY> <AWS_SECRET>
mc mirror local/ s3/your-bucket/
If you’ve already moved to managed data stores, your provider’s own backup tooling replaces these commands.
Dive deeper
Questions & Discussion