ObjectStackObjectStack

Backup & Restore

What state an ObjectStack deployment actually holds, how to back up each piece per database driver, and the restore drill to rehearse before you need it.

Backup & Restore

The go-live checklist requires a documented, tested backup/restore drill. This page is that drill: what to back up, how, and how to prove the restore works.

What state a deployment holds

An ObjectStack app is deliberately easy to back up because almost everything lives in one of four places:

StateWhere it livesBackup strategy
Business data (records, users, orgs, runtime-authored metadata, encrypted sys_secret values)The database behind OS_DATABASE_URLDatabase-native backup — see below
Authored metadata (objects, views, flows, …)Your project source + the compiled artifactGit. The artifact is rebuildable with os build; no runtime backup needed
Secrets (OS_SECRET_KEY, OS_AUTH_SECRET, DB credentials)Your secret managerEscrow the values themselves — see the warning below
The ObjectStack home dir (~/.objectstack or <cwd>/.objectstack: default SQLite DB under data/, uploaded files under data/uploads/, dev-minted keys)Local filesystemInclude in file backups on single-host deployments; empty on stateless containers that set OS_DATABASE_URL + OS_SECRET_KEY explicitly

A database backup without OS_SECRET_KEY is an incomplete backup. Every sys_secret value (encrypted settings, secret fields, datasource credentials) is encrypted under that one key. Restoring the database on a new host without the original key leaves those values permanently undecryptable. Escrow the key in your secret manager the day you generate it, and treat key + database as one backup unit.

Backing up the database

Use the native tooling of whatever OS_DATABASE_URL points at — ObjectStack adds no extra backup surface on top of the database.

PostgreSQL

# Logical backup (small/medium databases; restore with pg_restore)
pg_dump --format=custom "$OS_DATABASE_URL" > backup-$(date +%F).dump

# Larger deployments: continuous archiving / point-in-time recovery
# (WAL archiving, or your provider's managed snapshots)

SQLite (single host)

The database is a single file — but never copy it while the server is writing. Use SQLite's online backup instead:

sqlite3 /srv/data/app.db ".backup '/backups/app-$(date +%F).db'"

The default location when OS_DATABASE_URL is unset is <home>/data/objectstack.db under the ObjectStack home directory.

Managed databases (hosted Postgres, MongoDB Atlas, …)

Use the provider's snapshot, branching, or point-in-time-restore facilities. Nothing ObjectStack-specific applies. (Turso/libSQL applies only to ObjectStack Cloud-managed environments — the open framework does not ship that driver.)

Backing up uploaded files

The local storage adapter keeps uploads under OS_STORAGE_ROOT (default ./.objectstack/data/uploads). On single-host deployments, include that directory in the same schedule as the database so records and their attachments restore to the same point in time. Deployments using an external storage service (S3-compatible, etc.) inherit that service's durability and versioning instead.

The restore drill

Rehearse this on a scratch host before go-live, and again after any storage change. A backup you haven't restored is a hope, not a backup.

Provision a clean host

Fresh container or VM. Install Node 18+ and @objectstack/cli.

Restore the database

pg_restore --clean --if-exists -d "$OS_DATABASE_URL" backup-2026-07-14.dump
# or copy the SQLite file / restore the provider snapshot

Provide the original secrets

Set OS_SECRET_KEY and OS_AUTH_SECRET to the escrowed originals — not freshly generated values. Restore OS_STORAGE_ROOT contents if you use local file storage.

Boot from the artifact and verify

OS_ARTIFACT_PATH=./objectstack.json OS_PORT=8080 os start
curl -fsS http://localhost:8080/api/v1/health
curl -fsS http://localhost:8080/api/v1/ready

Then prove the restore end-to-end: sign in with a real account, open a record that existed before the backup, and read a value that lives in an encrypted setting (which exercises OS_SECRET_KEY).

Retention is not backup

The platform's lifecycle declarations bound telemetry data (activity 14d, job runs 30d, notifications 90d, audit 90d-hot) — deleted-by-policy data is gone from backups taken afterwards. If compliance needs longer, extend lifecycle.retention_overrides before go-live, and register an archive datasource if audit data must move to cold storage instead of being retained hot. See Production Readiness.

On this page