# Branching

> Create a branch of a SupaHost project, with or without its data, users and files, to test migrations safely. What's copied, what isn't, and how to ship changes without a merge.

Source: https://supahost.app/docs/platform/branching · Updated 2026-11-11

A branch is a separate copy of a project that you can break without consequences. Use one to try a migration on real data, to give a pull request its own backend, or to rehearse a risky change before running it on production.

Branching is available on Pro, Business and Enterprise. Only the owner can create or delete branches.

## How branches work on SupaHost

A branch is a full project in its own right. It has its own database, URL, Auth, Storage and keys, and it counts toward your plan's project allowance like any other project (and toward the 3-project limit during the trial). A branch of `app-one` named `app-one-orders` lives at `https://app-one-orders.acme.supahost.space`.

You can only branch from a main project, not from another branch. The branch name is the parent's name, a dash and your suffix, and the whole name can be at most 30 characters.

There's **no merge**. A branch is a place to test; you ship changes by applying the same migration to the parent. More on that below.

## Create a branch

1. Open **Dashboard → your project → Branches**.
2. Enter a suffix, for example `orders`, to create `app-one-orders`.
3. Choose whether to keep **Copy data, users and files** on (the default).
4. Create the branch.

The parent stays online the whole time. SupaHost copies its database with `pg_dump` and `pg_restore` into the new branch database.

## What's copied

| | With "Copy data, users and files" | Schema only |
|---|---|---|
| Tables, views, functions, triggers, RLS policies | Yes | Yes |
| Rows in your tables | Yes | No (tables are emptied) |
| pgmq queue messages | Yes | No |
| Auth users | Yes | No (`auth.users` is emptied) |
| Storage buckets | Yes | Yes |
| Storage files and `storage.objects` rows | Yes, files are copied | No |
| Migration history (`supabase_migrations`) | Yes | Yes |

**Never copied**, either way:

- Edge Functions and their secrets.
- Cron jobs. They're stored outside the project database, so a new branch starts with none.
- Auth settings (such as Site URL and redirect URLs) and OAuth providers.
- Custom domains.

The branch also gets **its own keys**. Your app needs the branch's URL and anon key to talk to it, which you'll find on the branch's Connect tab as usual.

### A note on real user data

With data copied, the branch has your real users and their emails. Auth settings aren't copied, so the branch starts with a Site URL of `http://localhost:3000` and no OAuth providers. Be careful testing anything that sends email from a branch, and delete branches holding production data when you're done. Choose schema only when you don't need the data.

## Testing a migration on a branch

Say you want to add a `status` column to `orders` and backfill it.

1. Create `app-one-orders` with data copied.
2. Run the migration on the branch, from Studio's SQL editor or through an AI agent with the MCP `apply_migration` tool:

```sql
alter table public.orders
  add column status text not null default 'pending'
  check (status in ('pending', 'paid', 'refunded'));

update public.orders set status = 'paid' where paid_at is not null;

create index orders_status_idx on public.orders (status);
```

3. Point a preview build of your app at the branch and check it works.
4. Check timing. If the `update` was slow on the branch's copy of the data, it will be about as slow on production.

## Shipping the change

Because there's no merge, you apply the same migration to the parent:

1. Keep the migration as a file in your repo, for example `supabase/migrations/20261111093000_add_order_status.sql`.
2. Apply that exact file to the parent project, the same way you did on the branch.
3. Delete the branch from the Branches tab.

Keeping migrations in files is what makes this reliable. See [SQL migrations](/docs/database/migrations) and [Migrations workflow: local to SupaHost](/docs/local-development/migrations-workflow).

## Branches for pull requests

A branch per pull request works, with two limits to keep in mind: each branch counts as a project while it exists, and creating one is a dashboard action by the owner. Schema-only branches hold no user data, so they are the safer choice for previews. See [Can I get a database per pull request?](/kb/preview-database-per-pr).

## Related

- [Projects](/docs/platform/projects)
- [Plans and limits](/docs/platform/plans)
- [Stopping cron jobs on a restored project or branch](/kb/stop-cron-after-restore)
