Backup & Restore¶
By the end of this page, you'll know how to back up KruxOS data and restore from a backup.
The backup CLI surface is kruxos state backup / restore / backups — there is no kruxos backup namespace. Daily backups also run automatically via a systemd timer at 02:00 UTC, and audit-log rotation runs at 03:00 UTC with a 90-day default retention.
What gets backed up¶
| Data | Location | Included |
|---|---|---|
| Agent state (persistent) | /data/kruxos/agents/*/state.db |
Yes |
| Shared state | /data/kruxos/shared/state.db |
Yes |
| Agent database | /data/kruxos/agents.db |
Yes |
| Approval queue | /data/kruxos/approval_queue.db |
Yes |
| Audit logs | /data/kruxos/audit/ |
Yes |
| Vault (encrypted secrets) | /data/kruxos/vault.db |
Yes |
| Policy files | /data/kruxos/policies/{system,org,agents/<name>}.yaml |
Yes |
| Configuration | /data/kruxos/config.yaml |
Yes |
| Installed packs | /data/kruxos/packs/ |
Yes |
| Model registry & provider config | /data/kruxos/models.yaml |
Yes |
| Model weights (GGUF) | /data/kruxos/models/ |
No (re-pull after restore) |
| Gmail read-replica | /data/kruxos/proxy/gmail/sync.db |
No (re-syncs) |
| Session state | In-memory | No (ephemeral) |
Model weights are deliberately excluded — they can be several GB each and are
re-fetchable from their source. The registry config (models.yaml) is captured, so after a restore you
re-pull the weights for the models it already lists (see
After a restore).
Create a backup¶
Full backup¶
Expected output:
Creating backup...
Agent state: ✓ (3 agents, 2.4 MB)
Shared state: ✓ (128 KB)
Agent database: ✓ (45 KB)
Approval queue: ✓ (12 KB)
Audit logs: ✓ (15.2 MB)
Vault: ✓ (encrypted)
Policies: ✓ (4 files)
Configuration: ✓
Backup saved: /data/kruxos/backups/backup-2026-03-29T14-30-00.tar.gz.enc
Size: 18.1 MB (encrypted)
Encryption
Backups are encrypted with AES-256-GCM. The encryption key is derived from your vault passphrase with Argon2id (plus a per-file salt), matching the vault's own key-derivation — so you need the vault passphrase to restore. Older backups (a single unsalted key-derivation) still restore: the format version is recorded in each file's header and detected automatically.
Scheduled backups¶
Daily backups run automatically on the appliance via a systemd timer at 02:00 UTC — see systemctl list-timers '*kruxos*'. No manual cron setup needed.
If you want to add a second schedule (e.g., hourly increments), use the host's cron:
echo "0 * * * * /usr/local/bin/kruxos state backup --out /data/kruxos/backups/incr-$(date +%H).tar.gz.enc" | crontab -
Backup to external storage¶
Copy the backup file to external storage:
# To a remote server
scp /data/kruxos/backups/backup-2026-03-29T14-30-00.tar.gz.enc user@backup-server:/backups/
# To cloud storage (example with rclone)
rclone copy /data/kruxos/backups/backup-2026-03-29T14-30-00.tar.gz.enc remote:kruxos-backups/
Docker volume backup¶
For Docker installations, back up the data volume. The --exclude='*/models/*'
keeps re-pullable model weights out of the archive (they can be several GB);
models.yaml and the rest of /data/kruxos are still captured:
docker run --rm -v kruxos-data:/data/kruxos -v $(pwd):/backup alpine \
tar czf /backup/kruxos-data-backup.tar.gz --exclude='*/models/*' /data/kruxos
Drop the --exclude if you specifically want a self-contained archive that
includes the downloaded weights.
Restore from backup¶
Prerequisites¶
- A running KruxOS instance (fresh install or existing)
- The backup file
- The vault passphrase used when the backup was created
Restore¶
Use kruxos state backups to list the available backup files first.
You'll be prompted for the vault passphrase:
Enter vault passphrase: ********
Restoring from backup-2026-03-29T14-30-00.tar.gz.enc...
Agent state: ✓ (3 agents restored)
Shared state: ✓
Agent database: ✓ (3 agents)
Approval queue: ✓ (2 pending)
Audit logs: ✓ (15.2 MB, chain verified)
Vault: ✓ (secrets decrypted and re-encrypted)
Policies: ✓ (4 files)
Configuration: ✓
Restore complete. Restart services to apply:
systemctl restart kruxos-gateway
After a restore: re-pull model weights¶
Backups (and kruxos migrate exports) capture models.yaml, but not the
model weight files under /data/kruxos/models/ — those are excluded because they
are large and re-fetchable. After restoring onto a fresh appliance, re-pull the weights for
the models the registry already lists:
# See the model catalog (the restored registry lists what was installed)
kruxos inference catalog
# Re-download the weights for a model by its catalog id
kruxos inference pull <id>
You can also re-pull from the dashboard's Settings › Local Models page. Local inference for a given model stays unavailable until its weights are back on disk; provider-backed (API) models are unaffected.
Verify after restore¶
# Check system status
kruxos status
# Verify agents
kruxos agent list
# Verify audit chain integrity
kruxos audit stats
Backup retention¶
Backups accumulate in /data/kruxos/backups/. Clean up old backups:
# List backups
ls -la /data/kruxos/backups/
# Remove backups older than 30 days
find /data/kruxos/backups/ -name "*.tar.gz.enc" -mtime +30 -delete
Next steps¶
- Updating KruxOS — apply updates with automatic rollback
- Monitoring — health checks and alerts
- Troubleshooting — common issues and solutions