# Forks

URL: https://briq.cloud/docs/concepts/fork

> Branch a briq, or a whole stack, before a change you might want to undo.

A fork is a new briq that starts from a copy of another briq's volume. The source keeps running and
never sees what the fork does. Keep the fork, or destroy it to throw the attempt away.

Use it to try what cannot be taken back (run a migration on a fork first), or to try two approaches
side by side.

```text
briq_fork({ briq: "bq_7kq2m9x1p4ab" })
→ forked into stack default · copied disk: processes start fresh on a copy of the source volume as of now
  bq_3m1x8kq2c7ta db-fork (postgres:16) running · fork of bq_7kq2m9x1p4ab · …internal · cost so far … · sleeps at 18:42 UTC unless used
  outputs:
    DATABASE_URL=postgres://postgres:…@…internal:5432/app
```

## What is copied

Each fork reports what it got in `copied`:

| `copied` | The fork gets                                        | When                                                 |
| -------- | ---------------------------------------------------- | ---------------------------------------------------- |
| `disk`   | The volume as it was at the fork                     | The source has a volume (every database recipe does) |
| `config` | Image, command, env, secrets and boot files, no data | The source has no volume                             |

Memory is not copied: processes start fresh on the copied disk, as after a power cut, and
databases recover as they are built to. For a clean copy, `briq_stop` the source first.

Not copied: its URL (expose the fork yourself), files written outside the volume (boot files
are config, and copied), and any link between the two. Destroying one leaves the other running.

A fork keeps its source's secrets (a database keeps the password it was created with). Its outputs
point at the fork.

## Names and stacks

| You pass        | The fork is                                                        |
| --------------- | ------------------------------------------------------------------ |
| `briq`          | `<name>-fork` in the same stack (then `-fork-2`, …)                |
| `briq`, `name`  | That name, in the same stack                                       |
| `briq`, `stack` | The source's name, in that stack                                   |
| `stack`         | Every briq of the stack, same names, in `<stack>-fork` (or `into`) |

Because names are kept, a forked app talks to the forked database with no configuration change:

```text
briq_fork({ stack: "shop", into: "shop-migration" })
→ forked into stack shop-migration · copied disk: …; config only: …
  bq_… db   running · fork of bq_…
  bq_… api  running · fork of bq_…
```

A briq that refers to a sibling (`{{briq:redis}}`) cannot be forked alone into a stack without a
briq of that name.

A stack fork is all or nothing: if one fork is refused, the others are destroyed and the call fails.
Briqs in `error` are left out and listed in `skipped`.

## Limits and cost

A fork is a new briq: it counts against the agent's policy and the team's credits, checked before
anything is copied, and bills per second. It runs in its source's region. A briq mid-move returns
`invalid_state` until the move lands.

## REST

```bash
curl -X POST https://api.briq.cloud/v1/briqs/bq_7kq2m9x1p4ab/fork \
  -H "Authorization: Bearer $BRIQ_API_KEY" -H "Content-Type: application/json" -d '{}'

curl -X POST https://api.briq.cloud/v1/stacks/shop/fork \
  -H "Authorization: Bearer $BRIQ_API_KEY" -H "Content-Type: application/json" \
  -d '{ "into": "shop-migration" }'
```

Both answer like `POST /v1/briqs`, with `copied` and `skipped` added.
