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

# External Workers

> How SDK processes connect to iii and register application logic.

External workers are application processes that use an iii SDK. They connect to the engine over WebSocket, register functions and triggers, and execute business logic when the engine invokes them.

## Lifecycle

1. The worker starts in Node.js, Python, Rust, or the browser.
2. The SDK connects to the engine WebSocket endpoint.
3. The worker registers functions, trigger types, triggers, and optional service metadata.
4. The engine routes matching invocations to that worker.
5. The SDK sends results or errors back over the same connection.

## SDKs

| SDK     | Package           |
| ------- | ----------------- |
| Node.js | `iii-sdk`         |
| Browser | `iii-browser-sdk` |
| Python  | `iii-sdk`         |
| Rust    | `iii-sdk`         |

External workers can run locally, in containers, on separate hosts, or in browser tabs. They only need network access to the engine WebSocket endpoint.
A Worker is any process that connects to the iii Engine over WebSocket using an SDK and registers Functions. The Engine routes incoming triggers to the correct Worker, which executes the handler and optionally returns a result.

Workers are independent processes — they can be written in any language, run anywhere, and crash without affecting other Workers.

## Diagrams

### Architecture

```mermaid theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
graph LR
    E[Engine]

    subgraph W1[Worker A]
        F1([Function A])
        F2([Function B])
    end

    subgraph W2[Worker B]
        F3([Function C])
    end

    W1 -- registerFunction --> E
    W2 -- registerFunction --> E
    E -- trigger --> W1
    E -- trigger --> W2
```

### Lifecycle Overview

```mermaid theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
flowchart TD
    Start(("registerWorker()")) --> Connecting
    Connecting -->|WebSocket open| Connected
    Connected -->|"Register<br/>functions & triggers"| Registering
    Registering -->|All registered| Ready
    Ready -->|Invocation received| Executing
    Executing -.-> RS[Result sent]
    Ready -->|shutdown| ShuttingDown
    ShuttingDown --> End((Exit))
    Ready -->|Connection lost| Disconnected
    Disconnected -->|Auto-reconnect| Reconnecting
    Reconnecting -->|Reconnected| Connected
    Reconnecting -->|Max retries| Failed
```

## Creating a Worker

A Worker is simply any collection of registered Functions and Triggers that has registered itself with the iii engine.
See [How to use Functions and Triggers](../how-to/use-functions-and-triggers) for details on registering
functions within workers. Read below for Worker responsibilities and configuration.

## What Workers Do

| Responsibility       | Description                                                                          |
| -------------------- | ------------------------------------------------------------------------------------ |
| **Function hosting** | Register Functions with the Engine and execute them when triggered                   |
| **SDK connection**   | Connect to the Engine via WebSocket, auto-reconnect on disconnect                    |
| **Language runtime** | Run in their own process in any iii-sdk supported language                           |
| **Isolation**        | Workers are independent processes. A crash in one Worker doesn't propagate to others |

## Init Options

The second argument to `registerWorker()` configures the Worker's behavior:

| Option                   | Type      | Default              | Description                                                               |
| ------------------------ | --------- | -------------------- | ------------------------------------------------------------------------- |
| `workerName`             | `string`  | `${hostname}:${pid}` | Name shown in the iii Console and in results from `engine::workers::list` |
| `invocationTimeoutMs`    | `number`  | `30000`              | Default timeout for `trigger()` calls in milliseconds                     |
| `enableMetricsReporting` | `boolean` | `true`               | Report CPU, memory, and event loop metrics to the Engine                  |
| `reconnectionConfig`     | `object`  | see below            | WebSocket reconnection behavior                                           |
| `otel`                   | `object`  | auto                 | OpenTelemetry configuration. Set `{ enabled: false }` to disable          |

### Reconnection Config

Workers reconnect automatically on disconnect using exponential backoff:

| Field               | Default | Description                                  |
| ------------------- | ------- | -------------------------------------------- |
| `initialDelayMs`    | `1000`  | First retry delay                            |
| `maxDelayMs`        | `30000` | Maximum retry delay cap                      |
| `backoffMultiplier` | `2`     | Multiplier applied to delay each attempt     |
| `jitterFactor`      | `0.3`   | Random jitter 0–1 to prevent thundering herd |
| `maxRetries`        | `-1`    | Maximum attempts. `-1` = infinite            |

> **Python naming:** Python uses snake\_case for these fields: `initial_delay_ms`, `max_delay_ms`, `backoff_multiplier`, `jitter_factor`, `max_retries`.

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
import { registerWorker } from 'iii-sdk'

const iii = registerWorker('ws://localhost:49134', {
  workerName: 'user-service',
  invocationTimeoutMs: 10000,
  reconnectionConfig: {
    initialDelayMs: 500,
    maxDelayMs: 10000,
    maxRetries: 10,
  },
})
```

## Worker Lifecycle

When a Worker connects, the SDK sends its metadata to the Engine via `engine::workers::register`:

```
runtime: 'node' | 'python' | 'rust'
version: SDK version
name: workerName
os: platform + arch
```

The Engine assigns a `worker_id` and the Worker's status transitions through:

```
connecting → connected → available / busy → disconnected
```

On disconnect — clean or crash — the Engine automatically removes all the Worker's registered Functions and Triggers. On reconnect, the SDK re-registers everything automatically.

## Worker Metadata

You can inspect all connected Workers at runtime:

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
const { workers } = await iii.trigger({
  function_id: 'engine::workers::list',
  payload: {},
})
// workers: WorkerInfo[] with id, name, runtime, version, os,
// status, connected_at_ms, function_count, functions[], active_invocations
```

```python theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
result = iii.trigger({
    "function_id": "engine::workers::list",
    "payload": {},
})
workers = result.get("workers", [])
```

<Info title="See also">
  For details on building and deploying Workers in production, see the [Quickstart tutorial](../quickstart) or the [SDK Reference](../api-reference/sdk-node).
</Info>
