| name | openclaw-backup |
| description | Back up and restore the OpenClaw state directory (config, workspace, sessions, skills) to a Tigris bucket. Scheduled backups, safe SQLite handling, point-in-time rollback via bucket snapshots, and zero-copy clones via forks. Use when the user wants their assistant's state to survive machine loss, move to a new machine, or roll back to before a bad update. |
Tigris Backup for OpenClaw
Back up ~/.openclaw (or $OPENCLAW_STATE_DIR) to a Tigris bucket, restore
it on any machine, and roll the whole state back to a point in time with
bucket snapshots. Solves the "my assistant's state should survive this box"
problem: machine loss, Gateway-update regressions, and moving between
machines.
What gets backed up
Everything in the state directory: openclaw.json, workspace files, skills,
credentials, and session history. SQLite databases are backed up with
sqlite3 .backup (a consistent copy), never by copying live database files —
copying a live SQLite file produces corrupt backups.
Consistency scope. Each SQLite database is captured internally consistent.
Whole-tree consistency (every file from the exact same instant) is only
guaranteed when the Gateway is idle, because files and databases are staged in
separate passes. For a strict point-in-time image, back up while the Gateway
is stopped, or use the bucket snapshot each run takes as the recovery point.
The backup script prints a note if it detects a running Gateway.
Object-storage limitations. Symlinks are dereferenced (their target content is stored), and Unix execute bits are not preserved across an S3 round-trip. Anything relying on execute bits in the state tree (for example skill scripts) should be reinstalled rather than restored.
Requirements
rclone and sqlite3 on PATH
- A Tigris bucket and access key
(create one)
- Optional, for snapshots/forks: the
tigris CLI and a
snapshot-enabled bucket
Setup
Add a Tigris remote to ~/.config/rclone/rclone.conf:
[tigris]
type = s3
provider = Other
access_key_id = tid_YOUR_ACCESS_KEY
secret_access_key = tsec_YOUR_SECRET_KEY
endpoint = https://t3.storage.dev
force_path_style = false
force_path_style = false matters: Tigris uses virtual-hosted-style
addressing.
Set the target bucket:
export TIGRIS_BACKUP_BUCKET=my-openclaw-backup
Back up
scripts/backup.sh
The script stages a consistent copy (SQLite via .backup, everything else
via rsync), then rclone syncs it to
tigris:$TIGRIS_BACKUP_BUCKET/openclaw-state/ so the prefix is a faithful
mirror of current state — a restore reproduces exactly what exists now, and
deleted files do not reappear. Replaced or removed objects are not destroyed:
they are archived under tigris:$TIGRIS_BACKUP_BUCKET/archive/<timestamp>/, so
deletions remain recoverable. If the tigris CLI is available and the bucket
is snapshot-enabled, each run also takes a named bucket snapshot as a
restorable point in time; a snapshot failure is reported loudly rather than
treated as success.
Backup and restore share a lock, so a scheduled backup cannot run while a
restore is mid-flight (and vice versa).
Schedule it with OpenClaw's own cron
(docs) or system cron. Daily
is a sensible default; the sync is incremental, so unchanged files cost
nothing to re-run.
Restore
On a fresh machine (or after wiping state), with rclone configured the same
way:
scripts/restore.sh
scripts/restore.sh --yes
Stop the Gateway before restoring. The restore downloads to a staging
directory first and only swaps it into place once the transfer fully
succeeds, so an interrupted restore never leaves partial live state. It then
restores owner-only permissions (S3 does not carry Unix modes, so credential
files would otherwise return world-readable). A best-effort check refuses to
run while an OpenClaw process is detected; override a false positive with
OPENCLAW_RESTORE_FORCE=1.
Roll back to before a bad update
If backups run on a snapshot-enabled bucket, every run is a point in time:
tigris snapshots list my-openclaw-backup
tigris mk my-openclaw-restore --fork-of my-openclaw-backup --source-snapshot <version>
Then restore from the fork
(TIGRIS_BACKUP_BUCKET=my-openclaw-restore scripts/restore.sh --yes). The
original backup bucket is never touched during a rollback.
Clone your assistant
Forks are zero-copy, so the same mechanism gives you a disposable twin: fork
the backup bucket, restore the fork onto a second machine, and experiment
with config, skills, or a Gateway upgrade against your assistant's real
accumulated state — while the original keeps running untouched.
Safety rules for agents
- Never run
restore.sh --yes without the user explicitly confirming they
want the local state replaced.
- The scripts enforce a shared lock, but still never start a backup and a
restore against the same state deliberately in parallel.
- The backup keeps superseded/deleted objects under the
archive/ prefix;
purging that prefix destroys recovery history, so leave it to the user.
- Credentials in
rclone.conf and the state directory are secrets; never
print them.