OpenClaw Backups: Archives, Snapshots, Scheduling, Replication
Learn how to back up OpenClaw state safely, covering full archives, per-database snapshots, scheduling, offsite copies, and continuous replication. Essential for operators protecting SQLite data from corruption.
Read this when
- You want a backup routine for an OpenClaw install instead of a one-off archive
- You want scheduled, offsite, or continuous backups without copying the whole database every time
- You need to restore OpenClaw state from a backup
Backups
SQLite serves as the storage engine for OpenClaw's authoritative data: a single control-plane database handles global coordination, while each agent gets its own database, all located beneath the state directory (typically ~/.openclaw). For the precise structure, refer to Database schemas. This section explains how to safeguard that data, covering full archives, individual database snapshots, automated scheduling, remote storage, and ongoing replication for deployments where re-uploading entire databases with every backup is impractical.
Copying live .sqlite, -wal, -shm, or -journal files directly is never a valid backup strategy. Because the Gateway writes to these databases continuously, a raw file copy taken mid-write risks being incomplete or corrupted. Every supported method described here safely captures committed data.
Warning
Sensitive material, including auth profiles, channel and provider credentials, session logs, and other confidential records, lives inside backups. Encrypt them at rest, limit access to the backup destination just as you would the live state directory, and rotate credentials if you have any reason to believe a backup was exposed. The same principles apply when moving between machines; see Migrating between machines.
Choose a path
- Complete, single-file, transportable:
openclaw backup createarchive. - Single database, validated and space-efficient:
openclaw backup sqlite create. - Content-addressed, incremental, versioned:
openclaw backup git create. - Scheduled protection: rely on the Gateway's built-in backup automation.
- Ongoing, incremental, minimal data loss: use Litestream for database replication.
Full archives
openclaw backup create --output ~/Backups/openclaw --verify
This produces a timestamped .tar.gz that bundles state, configuration, credentials, sessions, and workspaces by default, then checks the archive's manifest and payload. Databases within the archive are captured through SQLite's online backup API and compacted, making archive creation safe during Gateway operation. All flags, intentionally omitted volatile files, and verification specifics are documented in Backup CLI.
Each archive is a complete snapshot, so every run re-uploads the full dataset. They suit pre-update, reset, uninstall, or machine-migration scenarios, and work as a daily practice for smaller setups. For substantial workspaces or high-frequency backups, the snapshot or continuous replication options below are preferable.
On temporary container hosts, place the archive outside the container and treat openclaw backup restore as the primary recovery mechanism for constructing a fresh persistent state tree. Restoration only stages files; activation remains a separate offline deployment step.
Per-database snapshots
openclaw backup sqlite create --global --repository ~/Backups/openclaw-sqlite
openclaw backup sqlite create --agent main --repository ~/Backups/openclaw-sqlite
Each execution places one validated snapshot directory (manifest.json plus database.sqlite) into the repository directory. Snapshots undergo vacuuming, preventing deleted-page remnants from bloating them, and each one carries a SHA-256 that openclaw backup sqlite verify rechecks at a later point.
Snapshot repositories are simply local directories. Scheduling, uploading, retention, and boot-time restoration are left to the operator's discretion; the following sections address these topics.
Schedule backups
A Gateway-managed automation is the suggested cadence. This example snapshots every registered database daily and forwards the current branch to origin. Since pushing demands an origin remote be present in the repository first, initialize that once before turning on a pushed schedule:
openclaw backup git init --repository ~/Backups/openclaw-git --remote git@github.com:you/openclaw-backups.git
openclaw backup enable --repository ~/Backups/openclaw-git --every 24h --push
When no origin remote is set up, backup enable --push declines to create a schedule, so a fresh install can never end up with a recurring job whose pushes are doomed to fail.
By default, pushed schedules strip out credential-bearing tables, since an unattended recurring push would otherwise embed credentials permanently in remote Git history. To get full-fidelity remote backups, pass --include-secrets when you accept that risk and the remote is private; restoring from redacted history requires re-pairing devices and re-authenticating providers afterward. Local schedules that do not push retain complete fidelity, so restores are fully intact.
Scope can be narrowed with --global-only or --agent <id>. For a redacted Git history, add --exclude-secrets. Re-running the command replaces the fixed scheduled job rather than adding a duplicate. To turn it off:
openclaw backup disable
Enabling or disabling the schedule requires the Gateway to be reachable. No local fallback scheduler exists.
Your platform's own scheduler is an alternative. A nightly cron example that snapshots the control-plane database plus the main agent database:
0 3 * * * openclaw backup sqlite create --global --repository "$HOME/Backups/openclaw-sqlite" --json >> "$HOME/Backups/openclaw-backup.log" 2>&1
5 3 * * * openclaw backup sqlite create --agent main --repository "$HOME/Backups/openclaw-sqlite" --json >> "$HOME/Backups/openclaw-backup.log" 2>&1
On macOS, a launchd job functions identically; on servers set up via the hosting guides, a systemd timer fits naturally. --json produces one machine-readable result per run, so the log doubles as a backup audit trail. Prune old snapshot directories according to your own retention policy.
Every non-dry-run archive, local SQLite snapshot, and Git backup attempt is also logged in the shared state database. openclaw status displays the most recent attempt, and openclaw doctor recommends a one-off or scheduled backup when no successful run exists or the latest success is over 14 days old.
Copy backups offsite
Archives and snapshot repositories are ordinary files, so any sync utility works. An rclone example aimed at an S3-compatible bucket:
rclone sync ~/Backups/openclaw-sqlite remote:openclaw-backups/sqlite
Since every archive and local snapshot is a full copy, offsite syncs re-upload each new backup entirely. Deduplicating tools like restic cut storage at the destination but still consume full snapshots as input. When per-backup upload size is a concern, Git-backed snapshots or continuous replication are the better route.
Versioned backups to a Git repository
Git-backed backups convert each chosen database into deterministic schema.sql, manifest.json, and per-table JSONL files, then commit the entire run as one change. Unchanged database content yields no commit, so Git stores and pushes only content differences by construction. OpenClaw stages only the backup-owned global and agents paths, leaving unrelated files in the repository untouched.
openclaw backup git init --repository ~/Backups/openclaw-git --remote <private-git-url>
openclaw backup git create --repository ~/Backups/openclaw-git --all --push
openclaw backup git log --repository ~/Backups/openclaw-git
Dedicate a repository solely to OpenClaw backups. Existing global/ and agents/<agentId>/ scopes must be empty or hold a valid schema-version-1 OpenClaw backup manifest. OpenClaw will not overwrite any other scope, and an --all run checks every existing agent scope before removing stale backup-owned entries.
The current user must own the repository root, and it must not be group- or world-writable. This gets verified during init and on every create. On POSIX systems, check ownership and execute chmod 700 <repository> to fix unsafe permissions.
The repository is standard Git and works with any remote, GitHub included. Keep the remote private, since the default dump contains auth profiles, tokens, and other credential-bearing state. When a redacted history beats a credential-complete backup, --exclude-secrets excludes the documented secret tables; the exact list appears in Backup CLI.
Verify or restore one database at any commit without touching a live file:
openclaw backup git verify --repository ~/Backups/openclaw-git --ref <commit> --global
openclaw backup git restore --repository ~/Backups/openclaw-git --ref <commit> --agent main --target ./restored-agent.sqlite
Git restore reconciles derived search state: it rebuilds content-backed FTS5 indexes, defers transcript projection state for Gateway startup reconciliation, and leaves vector tables for memory indexing to regenerate. It then checks table hashes, SQLite integrity, and foreign keys.
Continuous replication with Litestream
Litestream is an open-source replication daemon built for SQLite. It runs beside the Gateway with no OpenClaw changes: it monitors each database's write-ahead log and streams incremental changes to object storage, taking periodic snapshots to keep restores quick. Only modified pages leave the machine, making it ideal when backups cannot afford to re-upload whole databases.
OpenClaw's databases operate in WAL mode, which is Litestream's sole hard requirement. A minimal litestream.yml replicating the control-plane database and one agent database to an S3-compatible bucket:
dbs:
- path: /home/user/.openclaw/state/openclaw.sqlite
replicas:
- url: s3://openclaw-backups/state
- path: /home/user/.openclaw/agents/main/agent/openclaw-agent.sqlite
replicas:
- url: s3://openclaw-backups/agents/main
Set up litestream replicate under your process supervisor, with one entry for each database you want to protect. When it's time to recover, restore to a brand-new path and bring it online without network access:
litestream restore -o ./restored-openclaw.sqlite s3://openclaw-backups/state
Only database bytes get replicated by Litestream. Configuration, credential files, and workspaces still depend on one of the file-based options described above, and the replicated data carries the same sensitivity as the archives, so enforce identical bucket permissions and encryption policies.
Restore
Recovery is intentionally manual; no live state gets overwritten in place.
Restore a full archive
Only use an archive you generated yourself or have reason to trust. openclaw backup verify validates the archive's structure and payload arrangement, but it won't authenticate the archive or make untrusted content safe to use.
Before attempting a full restore, check What gets backed up. Then run a single command to verify and unpack into a clean staging area:
ARCHIVE=./2026-03-09T08-00-00.000+08-00-openclaw-backup.tar.gz
openclaw backup restore "$ARCHIVE" --target ./restored-openclaw
The destination must be absent or empty. OpenClaw checks the archive structure, the manifest, hardlinks, symbolic-link containment, and SQLite databases prior to writing the target. A destination that already holds files is rejected, and a failed extraction removes its partial output. The live state directory is never touched by this command, and there's no force or in-place option. Handle the restored directory with care: it may hold credentials, auth profiles, sessions, and workspace data.
Warning
Restoring an archive rewinds time. Messaging-channel credentials that carry ratchet state, notably WhatsApp, can fall out of sync after a rollback and require relinking. Approvals and delivery/dedupe state also revert, so check pending approvals before the Gateway resumes. Plugin
node_modulestrees aren't included in archives; after activation, executeopenclaw plugins update <id>or reinstall viaopenclaw plugins install <spec> --force. Runopenclaw skills listor launch an agent session to rebuild the missingplugin-skills/symlink index from current plugin metadata.
The manifest captures archiveRoot, the original locations under paths, and an assets[] list. Every asset carries its kind, original sourcePath, and archivePath within the tarball. Treat those fields as authoritative; don't guess the archive root from the filename.
The archive structure looks like this:
<archive-root>/manifest.json
<archive-root>/payload/posix/<absolute-source-path-without-leading-slash>/...
<archive-root>/payload/windows/<DRIVE>/<rest>/...
<archive-root>/payload/relative/<relative-source-path>/...
To activate, halt the Gateway and any node hosts relying on the restored files. Either take a fresh backup of current state or move it aside. Then place the extracted state asset in its proper location, or set OPENCLAW_STATE_DIR to point at that asset, and run openclaw doctor before the Gateway restarts. On a different machine or with a different home directory, use the manifest to assign config, credentials, and workspace assets to their new locations. The rollback procedure is covered in Updating.
Restore a database
For a snapshot, openclaw backup sqlite restore <snapshot-directory> --target <new-database-path> writes a re-verified database to a new target. For Git history, openclaw backup git restore --repository <dir> --ref <commit> (--global | --agent <id>) --target <new-database-path> materializes and verifies a fresh database. For Litestream, litestream restore produces a new database file. Move the result into position while the Gateway is down, then bring the Gateway back up and inspect openclaw health and openclaw doctor.
If you're restoring onto a different OpenClaw version, run openclaw database preflight to preflight the database first; see Database schemas.
Related
- Agent workspace for keeping workspace files in a private git repository
- Backup CLI reference
- Database schemas
- Migrating between machines
- Updating