> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prodbreak.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Run parallel workers

> One instance per worker, provisioned by the CLI, assigned automatically by the plugin.

Because [one instance = one world](/concepts/worlds), parallel test workers must **not** share an
instance. Each worker gets its own. The CLI provisions them; your plugin assigns them.

## Boot N instances

```bash theme={null}
prod-break run deck --workers 4
```

This boots 4 instances, prints 4 `url`/`key` pairs, and exposes them via two ordered, comma-separated
env vars:

```
PRODBREAK_WORKER_URLS=http://localhost:8801,http://localhost:8802,http://localhost:8803,http://localhost:8804
PRODBREAK_WORKER_KEYS=pbw_aaa…,pbw_bbb…,pbw_ccc…,pbw_ddd…
```

## The plugin assigns each worker its pair

You don't wire this up — the plugin reads the env vars and gives worker *i* the *i*-th pair on first
use, keyed off the framework's worker id:

<CardGroup cols={3}>
  <Card title="Jest" icon="js">
    `JEST_WORKER_ID` (1-based) → the (i−1)-th pair.
  </Card>

  <Card title="Vitest" icon="bolt">
    `VITEST_WORKER_ID` / `VITEST_POOL_ID` → the matching pair.
  </Card>

  <Card title="pytest" icon="python">
    `pytest-xdist` worker `gw0`, `gw1`… → the matching pair.
  </Card>
</CardGroup>

`reset()` still runs between tests *within* a worker, so tests stay independent at two levels: a
private world per worker, and a clean slate per test.

## Single-worker runs

Sequential runs need no env CSVs — just point at one instance:

```
PRODBREAK_URL=http://localhost:8801
PRODBREAK_KEY=pbw_3f9a…
```

<Note>
  N workers means N processes — heavier than a single shared server, but it's what guarantees true
  isolation today. Lifecycle (evicting a stuck worker) is the CLI's job; a crashed worker doesn't
  auto-recover mid-run. The lighter "many worlds per instance" model is on the roadmap.
</Note>
