Skip to content
Beta — Truss is in public beta. Documentation is actively updated but may not reflect the latest changes. Report issues on GitHub.

Database Branching & Backups

Truss lets you create isolated copies of your database for testing, development, or migration verification. Branches are full PostgreSQL databases created from a template, giving you an exact copy of schema and data. Backups use pg_dump and support point-in-time recovery.

A branch is a PostgreSQL database created with CREATE DATABASE ... TEMPLATE. This gives you a byte-for-byte copy of the source database at the point of creation, including all schemas, data, indexes, and extensions. The branch is completely isolated — changes to the branch do not affect the source.

Terminal window
curl -X POST http://localhost:8787/api/branches \
-H "Content-Type: application/json" \
-d '{
"label": "feature-user-profiles",
"ttlHours": 24
}'
ParameterDescription
labelHuman-readable name (max 60 characters). Defaults to branch_{timestamp}
ttlHoursTime-to-live in hours. The branch auto-expires after this duration. 0 = no expiry

The response includes the branch ID, database name, creation timestamp, and size.

Terminal window
curl http://localhost:8787/api/branches

Response:

{
"branches": [
{
"id": 1,
"label": "feature-user-profiles",
"branch_db": "truss_branch_feature_user_profiles_abc123",
"status": "active",
"size_bytes": 8421376,
"ttl_hours": 24,
"created_at": "2025-01-15T10:00:00Z"
}
]
}

Each branch includes size_bytes computed via pg_database_size().

From the dashboard, click on a branch to switch your active database connection. The SQL workbench, schema browser, ERD, and all database tools reflect the branch’s state. You can run mutations freely without affecting the main database.

The active connection is scoped to your session. Other users continue using the main database.

Terminal window
curl -X DELETE http://localhost:8787/api/branches/1

The branch database is dropped entirely with DROP DATABASE. This action is irreversible.

Branches with a ttlHours value are automatically marked as expired after the specified duration. Expired branches are cleaned up on the next check cycle. This prevents forgotten branches from consuming disk space.

  • Feature development — branch before implementing a schema change, test it on the branch, then apply to production
  • Migration verification — create a branch, run migrations on it, verify the result before running on the main database
  • Data exploration — branch to run destructive queries (DELETE, TRUNCATE) without risk
  • Load testing — branch to test performance under synthetic load without affecting production

Branches are unlimited in self-hosted Truss — create as many as your disk space allows. Use ttlHours to auto-clean up short-lived branches.


Terminal window
curl -X POST http://localhost:8787/api/backups \
-H "Content-Type: application/json" \
-d '{"label": "pre-migration-backup"}'

Backups run pg_dump in the background. Up to 2 backups can run concurrently — additional requests are queued or rejected.

Terminal window
curl http://localhost:8787/api/backups

Response:

{
"backups": [
{
"id": 1,
"label": "pre-migration-backup",
"status": "completed",
"size_bytes": 52428800,
"created_at": "2025-01-15T10:00:00Z"
}
]
}

Backup statuses:

StatusMeaning
in_progressThe backup is currently running
completedThe backup finished successfully
failedThe backup encountered an error
Terminal window
curl -X POST http://localhost:8787/api/backups/1/restore

Restore replays the backup into a new branch database, not the main database. This lets you inspect the restored state before deciding to switch. From the dashboard, you can browse the restored branch, verify the data, and then switch your main connection if everything looks correct.

PITR lets you restore your database to a specific timestamp. This requires WAL (Write-Ahead Log) archiving to be enabled in your PostgreSQL configuration.

From the dashboard:

  1. Navigate to Database > Backups
  2. Select a backup
  3. Choose “Restore to point in time”
  4. Specify a target timestamp (must be within the WAL retention window)

The restore creates a new branch at the specified point in time.


Combining branches, backups, and migrations gives you a safe deployment workflow:

Terminal window
# 1. Create a backup before migration
curl -X POST http://localhost:8787/api/backups \
-H "Content-Type: application/json" \
-d '{"label": "pre-v2-migration"}'
# 2. Create a branch to test the migration
curl -X POST http://localhost:8787/api/branches \
-H "Content-Type: application/json" \
-d '{"label": "test-v2-migration", "ttlHours": 4}'
# 3. Switch to the branch and run migrations
# (do this from the dashboard, or switch programmatically)
# 4. Run safety checks
curl -X POST http://localhost:8787/api/migrations/check
# 5. Apply migrations on the branch
curl -X POST http://localhost:8787/api/migrations/idempotent/run
# 6. Verify — run queries, check schema, test the app
# 7. If everything looks good:
# - Switch back to main database
# - Run migrations on production
# - Delete the test branch
# 8. If something went wrong:
# - Delete the branch (no harm done)
# - Restore from backup if needed

The Database panel provides:

  • Branches tab — create, switch, and delete branches with size and TTL information
  • Backups tab — create backups, view status, restore to branch or point-in-time
  • Branch indicator — when connected to a branch, the dashboard shows a banner indicating the active branch name

MethodPathDescription
GET/api/branchesList active branches with sizes
POST/api/branchesCreate a new branch
DELETE/api/branches/:idDelete a branch (drops database)
GET/api/backupsList all backups
POST/api/backupsCreate a new backup
POST/api/backups/:id/restoreRestore backup to a new branch