Not yet released. This guide describes implemented changes awaiting rollout. Availability requires the corresponding backend and dashboard release.
Goal
Try a migration, test a fix or reproduce a bug on real data without touching your main database.Prerequisites
- A running PostgreSQL database
- Room for another branch on your plan (see Limits on your plan)
Workflow
1
Open the database and choose New branch, or run
stackshift db branch create shop-db --name fix-checkout --wait. Pick where it starts: now, a moment in the past or a saved backup.2
Get its address with
stackshift db branch url shop-db/fix-checkout. It has its own password, so your main database’s password never leaves main. Point your migration, test run or app at it.3
Change whatever you like. Nothing you do on the branch reaches your main database, and nothing that happens on main shows up on the branch.
4
When you’re done, reset the branch to match its source again, make it the main database, or delete it. If you do nothing, it expires on its own.
What a branch is
A copy of your database you can change freely. It has its own address and password, and sleeps when nobody’s using it. Reset it to match the original, make it the main one, or let it expire.- Branches can be made from your main database or from another branch, up to three levels deep. A branch’s source is fixed.
- A branch sleeps after 5 minutes without use, and wakes the next time something connects. See Sleep when idle.
- Branches don’t count toward the number of databases your plan allows.
- A branch never takes a backup history or a standby of its own. It can always be made again from its source.
- In the dashboard a branch shows Available, Sleeping, Failed or Needs attention. The API’s
stateiscreating,ready,resetting,promoting,failed,deletingorneeds_recovery.
Three ways to start a branch
- From now: ready in seconds, with everything your database holds at this moment. This works for databases up to 10 GB. For a bigger database, branch from a moment instead.
- From a moment: pick a time inside your history window. It takes a few minutes and works at any size. You need history for this: point-in-time restore on Starter (included on paid plans), or the retention window on Dedicated (7 to 35 days). A time outside the window is refused with the earliest time you can pick.
- From a saved backup: pick a backup you already have, or on Dedicated a restore point. Use this when the moment you want is older than your history window.
Limits on your plan
Longest life is the longest time you can ask a branch to stay before it is removed. Starter branches are included in your plan, with no hourly charge. When you reach a limit, you’re told which one and what to do: “You have 3 of 3 branches on your plan. Delete one, or move to a bigger plan.”
Dedicated databases allow 10 branches per database by default, with more on request, and no limit on how long a branch can live.
Reset a branch
Reset throws away every change on the branch and copies its source again. The branch keeps its address and password, so anything pointing at it carries on. If a reset fails, the branch keeps the data it had.- Dashboard: open the branch and choose Reset. CLI:
stackshift db branch reset shop-db/fix-checkout. - Reset is the quickest way to retry a migration. Reset the branch instead of making a new one each time.
- Over the API,
POST /api/v1/databases/{id}/branches/{branchId}/resetneeds anIdempotency-Keyheader, so a retry never resets twice.
Make a branch the main database
Making a branch the main database puts the branch’s data into your main database. Main keeps its address and password, so your apps need no change.- You type the name of your main database to confirm:
stackshift db branch promote shop-db/fix-checkout --confirm shop-db. The dashboard shows what will be lost first, for example “Changes to shop-db since you branched will be lost: 1,204 rows written since 14:02.” - A fresh backup of main is taken first. If that backup fails, nothing changes.
- Writes pause for a short moment while the data is swapped, about 5 to 15 seconds as a target.
- The old main data is kept for a day as a sleeping branch called
main-before-<date>, so you can undo the change for 24 hours. - Main starts a new backup history after the swap, then takes a full backup.
- If anything goes wrong during the swap, main goes back to how it was and the branch is untouched.
- It isn’t available while main has a standby. Turn the standby off first.
- Over the API,
POST /api/v1/databases/{id}/branches/{branchId}/promotetakes{"confirm_name": "shop-db"}and anIdempotency-Keyheader. Terraform can’t make a branch the main database.
Expiry
- A branch made by a person lives 7 days unless you choose another time. A branch made by an agent or for a pull request lives 24 hours.
- Choose a longer life up to your plan’s longest life, with
--ttl(24h,7d) or the Keep button. Extend it later withstackshift db branch extend shop-db/fix-checkout --ttl 7d, or withPATCH /api/v1/databases/{id}/branches/{branchId}and a newttl. - You’re warned 24 hours and 1 hour before expiry in the dashboard and by email, and in the pull request for a pull request branch.
- Expiry deletes the branch. An expired branch can’t be recovered, and this is stated when you create it.
- A branch with branches of its own can’t be deleted until those are gone, unless you add
--cascade --confirm <branch name>(in the API,?cascade=true&confirm=<branch name>with an Idempotency-Key).
Cost
- Starter: branches and sleep are included in your plan, within the limits above. No hourly line appears for them. Add-ons such as a standby or restore to any second aren’t bought again for a branch.
- Dedicated: a branch is billed per hour while it is awake, at the hourly rate of its size, plus a storage charge per GB-month for data that differs from main. A sleeping branch pays storage only. Making a branch the main database is free.
- As an example, a size priced at ₦16,000 a month costs about ₦21.92 an hour while awake. See https://stackshift.cloud/pricing for the current prices.
- Before a Dedicated branch is created you see the hourly price and confirm it. Over the API you get
409 price_confirmation_requireduntil you do. Agents quote the price first. - A branch is billed to the subscription of the database it came from. You can’t create one while that subscription is past due or suspended.
Use branches from your tools
Every branch is also a database of its own: its own ID works with credentials, metrics, logs and the SQL browser. Branches don’t appear in your database list, only under the database they belong to.- API:
GET /api/v1/databases/{id}/brancheslists the whole tree.POSTcreates a branch and answers202with an operation to follow until itsstatusissucceededorfailed.DELETE /api/v1/databases/{id}/branches/{branchId}deletes one. For routes on a branch,{id}is the database it was made from. fromisnow, or an object withtime,restore_point_idorbackup_id.ttlis24h,7dornever, within your plan’s longest life.sleep_after_minutesis 5 to 1440.- Add
-o jsonto any CLI command for machine-readable output, and--waitto wait until the branch is ready. The CLI exits with 8 for a plan limit, 9 for no room right now and 10 for a time outside the window. - Terraform creates and deletes branches. It never makes one the main database.
- The JavaScript and Python SDKs have a
branchesmodule underdatabases.withBranch(with_branchin Python) makes a branch that lasts 24 hours by default, gives your code its Shared connections address, and deletes the branch when your code finishes, which suits test suites. Both SDKs also havedatabases.sleepanddatabases.wake.
Availability
Branches are rolling out. If your database page doesn’t show Branches yet, it isn’t switched on for your account.Expected result
You have a separate database holding the data you chose. Changing it leaves your main database as it was, until you decide to make the branch the main one.
Common failures
Related guides
Branches for previews and agents
Give every pull request and every agent task a database it can’t hurt production with, and try migrations there first.
Sleep when idle
A database nobody is using goes to sleep and wakes on the next connection. Its address, password and data stay the same.
Back up and restore a database
Use durable recovery storage correctly and understand why backups are independent from portable SQL transfers.
Database connections and tunneling
Use private, direct public, or StackShift tunnel endpoints with TLS and explicit client IP policy.