Branching Workflows
DB9 can create a branch of any database — an independent copy with its own credentials, connection string, and data. Branches are useful for preview environments, isolated testing, safe schema migrations, and data recovery.
This guide shows how to create, use, and manage branches through the CLI and SDK.
Prerequisites
Section titled “Prerequisites”- A DB9 account with the CLI installed (see Quick Start)
- An existing database to branch from
db9 create --name productionHow Branching Works
Section titled “How Branching Works”When you create a branch, DB9 copies the full schema and data from the source database into a new, independent database. The branch gets its own:
- TiKV keyspace (isolated storage)
- Admin credentials
- Connection string
- Lifecycle (create, delete independently of the parent)
Changes to the branch do not affect the parent, and changes to the parent do not propagate to the branch.
Branch creation is asynchronous — the command returns immediately with status CLONING, and you poll until the branch reaches ACTIVE.
1. Create a Branch
Section titled “1. Create a Branch”db9 branch create production --name feature-authThe command returns immediately with the branch details:
Name: feature-authState: CLONINGParent: productionWait for the branch to be ready
Section titled “Wait for the branch to be ready”Poll the branch status until it reaches ACTIVE:
db9 db status feature-authOr in a script:
while true; do state=$(db9 db status feature-auth --json | jq -r .state) if [ "$state" = "ACTIVE" ]; then echo "Branch is ready" break elif [ "$state" = "CREATE_FAILED" ]; then echo "Branch creation failed" db9 db status feature-auth --json | jq .state_reason exit 1 fi sleep 2doneShow credentials on creation
Section titled “Show credentials on creation”db9 branch create production --name staging --show-secretsThis prints the admin password and connection string in the output. Avoid this in CI logs — use db9 db connect-token instead for short-lived credentials.
2. Connect to a Branch
Section titled “2. Connect to a Branch”A branch is a regular DB9 database. Connect with any PostgreSQL tool:
db9 db connect feature-authOr get the connection string:
db9 db status feature-auth --json | jq -r .connection_stringThen use it with psql, your ORM, or any PostgreSQL driver.
3. List Branches
Section titled “3. List Branches”db9 branch list productionShows all branches of a database with their state and creation time. Supports --output json and --output csv for programmatic use.
4. Delete a Branch
Section titled “4. Delete a Branch”db9 branch delete feature-authDeletion is permanent — there is no undo or trash. Deleting a branch does not affect the parent database.
5. SDK Usage
Section titled “5. SDK Usage”Use the TypeScript SDK for programmatic branch management:
import { createDb9Client } from 'get-db9';
const client = createDb9Client();
// Create a branch (first argument is the parent database ID)const branch = await client.databases.branch('production-db-id', { name: 'feature-auth'});console.log(branch.id, branch.state); // "CLONING"
// Poll until readylet status;do { status = await client.databases.get(branch.id); if (status.state === 'CREATE_FAILED') throw new Error(status.state_reason); await new Promise(r => setTimeout(r, 2000));} while (status.state !== 'ACTIVE');
// Use the branch — it has its own connection stringconsole.log(status.connection_string);
// Delete when doneawait client.databases.delete(branch.id);Practical Workflows
Section titled “Practical Workflows”Preview environments in CI
Section titled “Preview environments in CI”Create a branch per pull request for integration testing:
BRANCH_NAME="pr-${PR_NUMBER}"
# Create branch from productiondb9 branch create production --name "$BRANCH_NAME"
# Wait for itwhile [ "$(db9 db status "$BRANCH_NAME" --json | jq -r .state)" != "ACTIVE" ]; do sleep 2done
# Run migrations and tests against the branchdb9 db sql "$BRANCH_NAME" -f migrations/latest.sqlnpm test -- --database-url="$(db9 db status "$BRANCH_NAME" --json | jq -r .connection_string)"
# Clean updb9 branch delete "$BRANCH_NAME"Safe schema migration testing
Section titled “Safe schema migration testing”Test a migration against a real copy of production data before applying it:
# Branch productiondb9 branch create production --name migration-test
# Wait for ready# ...
# Apply migrationdb9 db sql migration-test -f migrations/0042_add_index.sql
# Validatedb9 db sql migration-test -q "SELECT count(*) FROM users"db9 db sql migration-test -q "EXPLAIN SELECT * FROM users WHERE email = 'test@example.com'"
# If satisfied, apply to productiondb9 db sql production -f migrations/0042_add_index.sql
# Clean up test branchdb9 branch delete migration-testTask isolation for agents
Section titled “Task isolation for agents”Give each agent task its own database branch so parallel agents don’t interfere with each other:
TASK_ID="task-$(uuidgen | head -c 8)"
db9 branch create shared-db --name "$TASK_ID"# ... wait for ACTIVE ...
# Agent works against isolated branchdb9 db sql "$TASK_ID" -q "CREATE TABLE scratch (id SERIAL, data JSONB)"db9 db sql "$TASK_ID" -q "INSERT INTO scratch (data) VALUES ('{\"result\": \"done\"}')"
# Clean up when task completesdb9 branch delete "$TASK_ID"Limits and Caveats
Section titled “Limits and Caveats”- Asynchronous creation — branches are not immediately ready. Always poll for
ACTIVEstate before connecting. - Full copy, not copy-on-write — each branch is an independent database with its own storage. Large databases take longer to branch.
- Max 2 concurrent branch creations — attempting a third returns a 429 error. Wait for in-progress branches to finish.
- Branches count toward database quota — anonymous accounts are limited to 5 databases total (including branches). Run
db9 claimto remove the limit. - No automatic merge — there is no built-in way to merge branch changes back to the parent. Export and re-apply manually.
- Deletion is permanent — deleted branches cannot be recovered.
- Branch naming — names must be unique within your account and cannot be empty.
Next Pages
Section titled “Next Pages”- CI Ephemeral Databases — disposable databases and branches in CI pipelines
- CLI Reference —
db9 branchcommand details and global flags - TypeScript SDK —
databases.branch()and programmatic management - Scheduled Jobs with pg_cron — automate branch cleanup or scheduled workflows
- Agent Workflows — using branches in agent pipelines
- Platform: Provisioning — database creation and lifecycle
- Recovery and Branch Lifecycle — branch states, automatic recovery, and backup expectations