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

# Workers

> Connect a worker, name its build and see which workers are connected.

A worker is your process that runs workflow steps. It opens one connection to
the project, registers its workflows and takes steps as runs need them.

## Connect

```ts theme={null}
import { connect } from "@duraton/sdk";

const worker = connect({
  url: "https://<slug>.<project-domain>/workflows/v1",
  apiKey: process.env.DURATON_WORKER_KEY ?? "",
  app: "shop",
  workflows: [welcome, fulfilOrder],
  buildId: process.env.GIT_SHA,
  maxConcurrency: 10,
});

await worker.ready;
```

| Option | What |
| - | - |
| `url` | The project's `/workflows/v1` base URL |
| `apiKey` | A worker (`dtn_wk_`) or secret (`dtn_sk_`) key |
| `app` | The app the workflows belong to |
| `workflows` | The workflows this worker runs |
| `buildId` | The build it runs; else `DURATON_BUILD_ID`; else one is derived from its workflows |
| `maxConcurrency` | Steps it runs at once |
| `drainTimeoutMs` | How long `close()` waits for steps in flight |
| `reconnect` | `{ initialDelayMs, maxDelayMs, stableAfterMs }`: defaults 500 ms, 30 s, 30 s |

A dropped connection is dialled again with backoff, and the worker registers
again each time. A revoked key, an invalid registration or invalid flow
control stops it for good: `closed` rejects with `ConnectRefusedError`.

## Stop

`worker.close()` takes no new steps, lets the ones in flight finish, then
closes; `worker.closed` settles once it has stopped.

## Builds

A worker's build is the `buildId` it passes to `connect` (or
`DURATON_BUILD_ID`); a worker that names none gets `m:` and a hash of the
workflows it registered.

| Where | Field | What |
| - | - | - |
| Run | `startedBuildId` | The build of the worker that took its first step |
| Run | `buildId` | The build of the worker that took its latest step; `GET /runs?buildId=` filters on it |
| Step | `buildId` | The build of the worker that ran that attempt |

Each is absent until a worker with a build takes the run.

A run in flight keeps the steps it has finished when you deploy new code: a
step is matched by its id, and a finished step is replayed from its stored
result. Change a step's id when its meaning changes, so the run runs the new
step instead of replaying the old result.

## Connected workers

`client.runners.list()`, or `GET /runners`, lists each worker connected now:

| Field | What |
| - | - |
| `app` | The app it registered |
| `kind` | `connect` |
| `buildId` | Its build |
| `sdk` | The SDK it runs |
| `connectedAt` | When its connection opened; may be absent |
| `inFlight` | Steps sent to it and not yet answered |
| `draining` | `true` once it stopped taking new steps |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.