---
title: "How it works"
description: "The parts of a cf-orbs install and how a job from Amp moves through them."
---

> Documentation Index
> Fetch the complete documentation index at: https://cf-orbs-site.mdick85.workers.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# How it works

A cf-orbs install has three parts, and all three run in your Cloudflare account:

- **The Worker.** It starts, pauses and deletes orbs, and keeps track of snapshots. It holds its state in Durable Objects (Cloudflare's small stateful objects, each with its own storage).
- **The provider container.** It runs `amp orb provider`, which takes jobs from Amp over an outbound connection.
- **The orbs.** One Cloudflare Container for each Amp thread.

## Terms

- **Control plane.** The Worker and its Durable Objects. They start, pause and delete orbs.
- **Dispatch.** `dispatch.sh`, the small shell program that the provider runs once for each job. It passes the job to the control plane.
- **Bootstrap.** `amp orb bootstrap`, the Amp start-up step inside an orb. It connects the orb to Amp.
- **Watchdog.** A timer in each orb's Durable Object. It checks awake orbs and pauses the ones that stay awake too long.
- **Prewarm.** Throwaway orb instances that the Worker starts after a deploy. They pull the new image onto hosts and prove that the image starts.
- **tini.** A small init program. It runs as process 1 in the orb and reaps stopped processes.

## Diagram

```text
Amp ---outbound---> provider container (amp orb provider -> dispatch.sh)
                          |  POST /v1/orbs/<id>/ops   (bearer: control token)
                          v
          Worker "cf-orbs"
            |- OrbSession Durable Object (one per orb) --> orb container
            |- Registry Durable Object (snapshots, awake orbs)
            '- ProviderHost Durable Object --> provider container
```

## The parts

| Part | Job |
| --- | --- |
| Worker | Serves the `/v1` API. Holds all state in Durable Objects. |
| `OrbSession` | One for each orb, named `orb:<ORB_ID>`. Runs spawn, pause and delete. Owns the container, the snapshot and the watchdog alarm. |
| `Registry` | One for each install. Maps an Amp snapshot id to a Cloudflare snapshot. Lists every snapshot. Counts awake orbs for `maxRunning`. |
| `ProviderHost` | Starts the provider container and keeps it running. |
| Provider container | Runs `amp orb provider` with the Amp provider token. For each job, it runs `dispatch.sh`. |
| Orb container | The Amp orb image plus `tini`. One for each thread. |

For more on each part, see [Provider and dispatch](/docs/concepts/provider-and-dispatch/), [Orb lifecycle](/docs/concepts/orb-lifecycle/) and [Orb image](/docs/concepts/orb-image/).

## How a job moves

1. Amp sends the provider one of three operations: `spawn`, `pause` or `delete`.
2. `dispatch.sh` turns the job into one Worker operation: `POST /v1/orbs/<id>/ops`.
3. `dispatch.sh` then long-polls `GET /v1/ops/<opId>` and prints each progress line. Amp shows the lines in the thread setup log.
4. The operation ends as `succeeded` or `failed`, and `dispatch.sh` exits 0 or 1.

The same job always returns the same operation, so a retry from Amp attaches to the operation that's already running.

## Spawn order

On spawn, the first match wins:

1. The orb container is running: reuse it.
2. The orb has its own snapshot: restore it.
3. The orb is new, and Amp sent a project snapshot id that maps to a snapshot: restore that, and skip repo setup.
4. Otherwise, start from the orb image.

After that, `amp orb bootstrap` starts in its own process group. The spawn succeeds when the bootstrap runs and Amp reports it connected.

## Control token and API

The CLI and the provider use the same `/v1` API, with the control token as the bearer. The control token is in `.cf-orbs/control-token` (mode 600) and in the Worker secret `CONTROL_TOKEN`.

In Cloudflare provider mode, `dispatch.sh` reaches the API at `http://control.internal`. The Worker routes that host inside Cloudflare, so the provider sends no bearer. The public API is on as well, and it needs the bearer.

If `CONTROL_TOKEN` isn't set on the Worker, every public route returns 404.

## Watchdog

A 60 s alarm checks each awake orb. It pauses the orb if it has stayed awake longer than `maxAwakeHours`, or if its bootstrap died. The `alarmSeconds` key sets the interval.

Source: https://cf-orbs-site.mdick85.workers.dev/docs/concepts/how-it-works/index.mdx
