Backup & restore
Take a consistent backup of your staqly data while it runs, and restore it when you need to.
Everything staqly knows (posts, channels, schedules, history, settings and uploaded files) lives in one data directory. Back it up regularly, and always before an upgrade. Backups are taken while staqly keeps running; restoring needs a short stop.
With STORAGE_DRIVER=s3 the uploaded files are in a bucket, not in the data directory: back the
bucket up with your provider's tools. See Media storage.
What to back up
| File | What it is |
|---|---|
workspace.db | The SQLite database, the job queue included (scheduled posts and pending retries). Back it up with the backup command, never by copying the file. |
uploads/ | Uploaded media, one folder per workspace (uploads/workspaces/<id>/). Their thumbs/ folders are a cache staqly rebuilds; you can skip them. |
secret.key | Decrypts channel credentials and developer app secrets. Only there if you haven't set STAQLY_SECRET_KEY. Without it every channel has to be reconnected. |
notify_secret.key | Decrypts alert secrets. Only there if you haven't set NOTIFY_SECRET_KEY. |
access_token | The Community Edition's access token. Optional: without it a restored install makes a new token and your agents need the new one. |
They are in ~/.local/share/staqly with the binary (or your --data directory), and in the
staqly-data volume at /data with the Docker image.
Never copy workspace.db from a running server
Under WAL the latest commits may live only in workspace.db-wal, and a file copy taken
mid-write can be torn. Use the backup command below.
Back up
Settings → Backups in the dashboard shows the backup commands for your install (binary or Docker), ready to copy. On Staqly Cloud it lists the workspace's backups instead.
staqly serve backup copies the database only, so archive the uploads next to it.
Back up the database
umask 077
mkdir -p ~/staqly-backups/2026-10-13
staqly serve backup ~/staqly-backups/2026-10-13/workspace.dbThis works while staqly serve is running. Add --data (e.g.
staqly serve --data ~/staqly-data backup ~/staqly-backups/2026-10-13/workspace.db) if you don't use
the default data directory.
Archive uploads and the keys
cd ~/.local/share/staqly
tar czf ~/staqly-backups/2026-10-13/uploads.tar.gz --exclude='uploads/workspaces/*/thumbs' \
uploads $(ls secret.key notify_secret.key access_token 2>/dev/null)Take the database first and the uploads second (see Why the order matters).
Store it off the machine
Copy the backup folder somewhere else, encrypted.
Restore
Restoring replaces all current data with the backup.
Stop staqly
Press Ctrl-C. If it runs in the background, staqly service uninstall stops it (your data is kept);
run staqly service install again afterwards.
Put the backup in place
cd ~/.local/share/staqly
rm -f workspace.db workspace.db-wal workspace.db-shm
cp ~/staqly-backups/2026-10-13/workspace.db workspace.db
rm -rf uploads
tar xzf ~/staqly-backups/2026-10-13/uploads.tar.gz
chmod 600 workspace.dbDelete the -wal and -shm files: stale WAL files must not be replayed onto the restored
database.
Start staqly again
staqly servePending migrations run automatically on start.
Sessions and API keys come back as they were at backup time. The access token is the
access_token file: restored with it, agents keep working; otherwise the install keeps the token
it has (or makes a new one).
Schedule backups
Run the backup from cron (or a systemd timer), then ship the backups off the machine.
Save the two backup steps as a script:
#!/bin/sh
set -eu
umask 077
out="$HOME/staqly-backups/$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$out"
"$HOME/.local/bin/staqly" serve backup "$out/workspace.db"
cd "$HOME/.local/share/staqly"
tar czf "$out/uploads.tar.gz" --exclude='uploads/workspaces/*/thumbs' uploads $(ls secret.key notify_secret.key access_token 2>/dev/null)Make it executable (chmod +x ~/.local/bin/staqly-backup) and run it every night at 3:00:
0 3 * * * $HOME/.local/bin/staqly-backup >> $HOME/staqly-backups/backup.log 2>&1How backups work
A consistent snapshot
The backup command (staqly serve backup or server backup in the container) runs SQLite's
VACUUM INTO: a transactionally consistent, compacted copy taken while the server keeps
serving requests. The search index is rebuilt in the copy.
Why the order matters
Media files are written before the database row that references them and are never modified afterwards. Taking the database snapshot first and the uploads second therefore never yields a row pointing at a missing file.
Backups contain secrets
The database holds webhook signing secrets (in plain text — they are needed to sign), hashed
API keys and sessions, sealed channel credentials and encrypted alert secrets; secret.key and
notify_secret.key decrypt them. Run the backup commands with umask 077 as above, so only you can read the
copies, and keep it that way: store backups encrypted, and don't commit them or put them on
shared drives.
Staqly Cloud workspaces
On Staqly Cloud, workspace admins on a paid plan get backups in Settings → Backups:
Create backup builds a ZIP of the whole workspace (collections, posts, channels without
credentials, schedules, events and media), and each ready backup has a Download button for 24 hours. These are the
workspace exports from Data export & privacy
(POST /v1/workspace/export, GET /v1/workspace/exports). On the Starter plan the tab points
to the data-only export in Settings → Data & privacy (no media files) instead.
These downloads are your own copy of the workspace.
From a checkout (Compose)
If you develop staqly from the repository with Docker Compose,
make backup (scripts/backup.sh) runs the Docker steps above against the Compose volume
staqly_staqly-data and writes backups/<timestamp>/workspace.db and uploads.tar.gz
(uploads without the thumbs cache, plus secret.key, notify_secret.key and access_token if
present), all owner-only.
make restore BACKUP=backups/<timestamp> (scripts/restore.sh) restores one; it asks for
confirmation (FORCE=1 skips it). STAQLY_CONTAINER and STAQLY_VOLUME select another
container or volume.