# Branches

> A branch clones the database with data, the bucket, and every compute service.

A branch is a full, isolated clone of your environment. Every project starts on `main`; a branch forks from a parent and lives until you delete it. Use branches for staging, per-agent tasks, and per-pull-request environments.

## What gets cloned

| Piece | On the new branch |
| --- | --- |
| Postgres | Copy-on-write clone with the parent's data, own connection string |
| Storage | Copy-on-write fork of the bucket's objects |
| Compute | A clone of each app at its own URL, running the parent's image |
| Secrets | Copied, with service bindings remapped to the branch's services |
| Managed databases (`redis`/`mysql`/`mongodb`) | A fresh, empty instance, with no data cloned |
| Compute `/data` volume | Same size, empty (self-hosted InstaCloud OSS forks the volume files instead) |

<Note>
On self-hosted InstaCloud OSS, a branch is a fork on disk: the Postgres data directory and every compute volume are reflink-copied, so `branch create` returns in about a second whatever a sleeping database weighs, and the bucket objects are synced. A database that is awake is streamed with `pg_basebackup` instead, in time proportional to its size, because a file-level copy of a live server is not consistent. Compute volumes have no such streaming path, so they are copied whether the app is running or not: stop the group first if you need a quiescent copy.
</Note>

## Creating and switching

```bash
insta branch create staging
insta branch switch staging
insta secrets
```

`create` forks from your current branch. Choose the parent explicitly with `--from <branch>`. Creating does not switch you: `switch` rewrites the directory link (`.insta/project.json`), after which every command targets the branch. Rerun `insta secrets` to refresh `.env`.

## Branch URLs and credentials

Each branch's compute services get their own URLs, printed on deploy and listed by `insta agent manifest`. Credentials are per-branch: `insta postgres url` prints the branch's connection string, and the branch's copied bindings point at the branch's own services, so work done on a branch stays on that branch. Commands that accept `--branch` (`secrets`, `deploy`, `storage delete`, and others) can still reach another branch when you tell them to.

## Merging

```bash
insta branch merge staging --into main
```

Merging is structural and additive: a service that exists on the source but not the target is created there, empty, so deploy to it afterwards. Data never merges: promoting data changes means running your migrations against the target and deploying. Existing services are skipped with a reason (`exists`, `cap`). On self-hosted InstaCloud OSS, a merged compute group is created and deployed with the source branch's image against the target's own database and bucket.

## Limits

- 10 branches per project.
- Names: lowercase letters, digits, and dashes, up to 39 characters, starting with a letter or digit.

## Deleting

```bash
insta branch delete staging
```

Tears down the branch's database, bucket fork, compute, and secrets.
