# Openclaw Backup

> 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.

- Skill: `tigrisdata/openclaw-backup` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds add tigrisdata/openclaw-backup`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tigrisdata/openclaw-backup/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tigrisdata (https://skillmd.com/u/tigrisdata)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/tigrisdata/openclaw-backup

---


# 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](https://www.tigrisdata.com/docs/iam/manage-access-key/))
- Optional, for snapshots/forks: the
  [`tigris` CLI](https://www.tigrisdata.com/docs/cli/) and a
  snapshot-enabled bucket

## Setup

Add a Tigris remote to `~/.config/rclone/rclone.conf`:

```ini
[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:

```bash
export TIGRIS_BACKUP_BUCKET=my-openclaw-backup
```

## Back up

```bash
scripts/backup.sh
```

The script stages a consistent copy (SQLite via `.backup`, everything else
via rsync), then `rclone sync`s 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](https://docs.openclaw.ai/automation/cron-jobs)) 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:

```bash
scripts/restore.sh          # dry-run: shows what would change
scripts/restore.sh --yes    # actually restores
```

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:

```bash
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.

