Back up and move Orbit state
Orbit keeps state in two places. This page shows which files you cannot regenerate, how to copy them safely, how to check a restore, and which command to use when you move tasks instead of restoring a machine.
Where state lives
Section titled “Where state lives”User/machine state is under ~/. --root points Orbit at a
different data directory and takes precedence over every other source.
Workspace state is under . in each checkout.
Back up and restore these. You can’t regenerate them.
~/: global settings and this machine’s identity in. orbit/ config. toml [machine](id,name,task_prefix).~/: the registry of workspaces on this machine, with owner and replica roles.. orbit/ workspaces. json ~/: the canonical task bundles.. orbit/ tasks/ workspaces/ <ws-id>/ <task-id>/ ~/: the task-ID allocator and its issued-ID high-water mark, plus workspace bindings. Its index rows can be rebuilt with. orbit/ tasks/ index. sqlite orbit; the allocator and bindings can’t.task reindex ~/: audit events, job runs and checkpoints, reservations and routine state.. orbit/ orbit. db ~/: the tag taxonomy and legacy friction record files.. orbit/ frictions/ ~/: only the YAML you wrote and any. orbit/ resources/ .copies. The shipped defaults are reseeded byretired-managed/ orbit.init <repo>/and. orbit/ config. yaml config.: workspace identity and optional workspace settings.toml <repo>/: workspace overrides for activities, jobs, executors and policies.. orbit/ resources/ <repo>/: the audit output that rows in. orbit/ state/ audit/ blobs/ orbit.point to. Keep it withdb orbit.if detailed output matters.db <repo>/: run worktrees, which can hold uncommitted candidates from active or failed runs. Keep them until the run is settled.. orbit/ state/ worktrees/
You can lose and regenerate these: <repo>/ (rebuilt by
orbit ), ~/, and ~/.
The state and backup runbook
has the complete inventory, including retired directories you can delete.
Task publication is not a full backup. It covers task records only. See Publish and restore tasks.
Take a backup
Section titled “Take a backup”Orbit’s SQLite files (orbit. and tasks/) run in WAL mode, so a
committed change can sit in a -wal file until SQLite checkpoints it. Copying a
database file while Orbit may write is not a safe backup, even when you also copy
its -wal and -shm files. A checkpoint between the copies can leave committed
changes out of the copy, and the copy can still pass quick_check. Pick one of these.
Cold copy. Stop Orbit first: the dashboard, MCP servers, scheduled timers and any running drain. Then copy the whole directory.
cp -a ~/.orbit ~/orbit-backup-$(date +%F)A plain file copy of the database files is safe only in this stopped state, or
from one atomic filesystem snapshot of the volume that holds ~/, taken at a
single instant.
Live snapshot of one database. This works while Orbit runs and writes a
checkpointed file with no sidecars. It uses the sqlite3 shell, which Orbit does
not install for you.
sqlite3 ~/.orbit/orbit.db "VACUUM INTO '/backups/orbit.db'"# orsqlite3 ~/.orbit/orbit.db ".backup /backups/orbit.db"A live snapshot covers one database. For the whole machine, use the cold copy or an
atomic filesystem snapshot. Keep recovery copies outside ~/, because deployment
cleanup (orbit ) treats orbit. files there as disposable.
Restore and verify
Section titled “Restore and verify”Stop local Orbit processes first. This overwrites the current store database, so keep a copy of it until verification passes.
cp /backups/orbit.db ~/.orbit/orbit.dbrm -f ~/.orbit/orbit.db-wal ~/.orbit/orbit.db-shm # stale sidecars from the old file
orbit task reindex # rebuild task index rows from the bundlesorbit search reindex # rebuild the task search indexorbit doctor --deep # scan every database pageorbit should report ok for the database row. Then run
orbit or orbit on a task you know exists.
If you restored task bundles by copying ~/ rather than
orbit., run orbit afterwards. Restore tasks/
along with the bundles. It alone records the highest task ID this machine has
issued, and a bundle copy without it makes Orbit refuse new task IDs until the
high-water mark is set again. The recovery steps are in the runbook linked above.
Restore tasks, or move them
Section titled “Restore tasks, or move them”Three situations look alike and take different commands.
| You want to | Use |
|---|---|
| Recover the same machine and workspace after a loss, from a publication snapshot. | orbit . Restore config. and workspaces. first so the machine and workspace keep their identity. |
| Copy tasks to a different machine or workspace, where the identity differs. | orbit and orbit . |
| Keep read-only copies of another machine’s tasks current. | orbit , repeatedly. |
Publication restore needs the same authority: the owner checkout, the same logical workspace and source remote, and the same machine ID. It refuses a destination that already has tasks and never renumbers. Export and import make no such assumption; they exist for the case where that identity is gone or deliberately changed.
Export tasks to an archive
Section titled “Export tasks to an archive”orbit packs one workspace’s task bundles into a tar.
archive. It does not include audit events, run history, configuration or machine identity.
orbit task export --output tasks.tar.zst # every task in the current workspaceorbit task export --ids BOX-00012,BOX-00040 -o some-tasks.tar.zst # only these tasksorbit task export --task-workspace <ws-id> -o other.tar.zst # another workspace on this machine--all is the default when you omit --ids. Export fails if the workspace has
no tasks, or if an ID you named isn’t registered to it. It writes the archive
beside the destination and replaces any existing file only when the archive is
complete, so a failed export leaves an earlier backup alone. Archives hold only
regular files and directories.
Task text and attachments can hold sensitive detail. Treat the archive like the task store itself.
Import tasks
Section titled “Import tasks”orbit task import tasks.tar.zstorbit task import tasks.tar.zst --task-workspace <ws-id> --on-conflict renumberImport checks the archive and every bundle before it changes anything, so a corrupt
or incompatible archive writes nothing. Without --task-workspace, tasks go to the
archive’s source workspace; if this machine doesn’t know that workspace, import
registers it without a checkout. To land them in an existing workspace, pass its
workspace_id (from . in that checkout).
A task collides when its ID already exists locally with different content. A
task that is already there byte for byte is reported already-present under every
policy. --on-conflict decides what happens to a collision:
| Value | Behavior |
|---|---|
renumber (default) |
Gives the incoming task a new local ID and rewrites relations among the imported tasks. Writes an old-to-new map to <archive>.. |
skip |
Keeps the local task and drops the incoming one (skipped). |
fail |
Aborts the whole import at the first collision. |
owner-wins |
Never renumbers. See below. |
Tasks with free IDs keep them under every policy. A renumber import that
had collisions is not repeatable: the local task still differs from the original, so a second
run mints another new ID. Import such an archive once and keep the printed
. as the record of what landed.
Illustrative output after a task was edited on the machine that minted it:
$ orbit task import tasks.tar.zstimported into workspace 'ws_proj' already-present BOX-00000 renumbered BOX-00001 -> DEV-00002 id mapping written to tasks.tar.zst.idmap.jsonKeep mirrors current with owner-wins
Section titled “Keep mirrors current with owner-wins”Each machine mints IDs under its own task prefix, and the machine whose prefix a task
carries is its only writer. A copy on another machine is a read-only mirror.
owner-wins refreshes those mirrors from the owner’s export:
# On the machine that mints BOX- tasksorbit task export --output box-tasks.tar.zst
# On the machine holding the mirrororbit task import box-tasks.tar.zst --on-conflict owner-winsFor each colliding ID, import decides from the prefix alone. A task under another
machine’s prefix is replaced by the incoming copy and reported updated. A task under
this machine’s prefix is left alone and reported skipped-local-owned, so an archive
can’t overwrite your own work. Nothing is renumbered, no . is written, and
running the same archive again reports already-present, so it is safe to repeat on a
schedule. Import tasks that others depend on first: a cross-machine depends_on
resolves only once its target’s mirror has landed.
Only the prefix decides, so owner-wins never moves ownership: a mirror stays
read-only on the machine that imported it.
Check the result
Section titled “Check the result”orbit task list --workspace <name>orbit doctororbit reports bundles missing from the task index. If it does, run
orbit before treating an empty list as lost tasks.
See Run Orbit across hosts for how an ID routes to its owner
and the CLI reference for the command list.