> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://docs.ampdb.io/api/mcp` to find what you need.

# Jobs and Workers

Amp does its work in jobs: extracting a chain's data, computing a derived dataset's tables, deleting files nobody needs
anymore. The controller schedules jobs, and workers run them. Most of the time, you don't create jobs yourself:
deploying a dataset does.

## Jobs

A job is one piece of work that Amp schedules and runs, with an ID, a status, and a history of what happened to it.
There are a few kinds:

* **Materialization**: fills a dataset's tables. For a raw dataset, it extracts blocks from a
  [provider](/get-started/concepts/providers). For a derived dataset, it runs the dataset's SQL over its dependencies.
* **Garbage collection**: deletes the files a dataset's tables no longer use.
* **Export**: copies a dataset's tables into another database, like PostgreSQL or Snowflake.

### What deploying does

When you deploy a dataset, Amp schedules three jobs at once:

* A **parent job**, which does no work itself. It watches the other two, and its status sums them up.
* A **materialization job**, which fills the dataset's tables.
* A **garbage collection job**, which runs periodically, to delete the dataset's unused files.

`ampctl dataset deploy` prints the parent job's ID, and `ampctl dataset status` shows its status and the tables'
progress:

:::terminal
```bash
ampctl dataset deploy acme/eth_mainnet@1.0.0 --end-block 24000099
```

```
✓ Dataset deployed successfully
→ Job ID: 1
```
:::

A materialization job runs in two phases. It first catches up, from the dataset's start block to the chain's latest
block. Then it follows the chain, extracting each new block as it's produced. With `--end-block`, it stops at that block
instead, and completes.

### Statuses

| Status           | Meaning                                                                                |
| ---------------- | -------------------------------------------------------------------------------------- |
| `SCHEDULED`      | Waiting for its worker to start it                                                     |
| `RUNNING`        | Running                                                                                |
| `COMPLETED`      | Finished its work, like reaching its end block                                         |
| `ERROR`          | Failed, and will be retried                                                            |
| `FATAL`          | Failed for good: the failure can't be fixed by retrying, or the job ran out of retries |
| `STOP_REQUESTED` | Asked to stop: its worker hasn't stopped it yet                                        |
| `STOPPING`       | Stopping                                                                               |
| `STOPPED`        | Stopped, as asked                                                                      |
| `CANCELLED`      | A periodic job's failed run, given up for the next scheduled run                       |

`COMPLETED`, `FATAL`, and `STOPPED` are final: the job stays there. Periodic jobs, like garbage collection, are the
exception: one in `COMPLETED`, `FATAL`, or `CANCELLED` runs again at its next scheduled time. `STOPPED` is final for
every job, periodic or not: stopping a periodic job ends its schedule. [Job Lifecycle](/managing-amp/jobs/lifecycle)
shows every transition.

### Retries

Most failures are temporary, like an endpoint that times out or limits requests. When a job fails, it goes to `ERROR`,
and Amp starts it again after a delay: 1 second after the first failure, then 2, 4, 8, and so on, up to an hour.
By default, it keeps retrying until you stop the job. You can limit retries when you deploy: see
[Retries](/managing-amp/jobs/retries).

## Workers

A worker is an `ampd` process that runs jobs. In [solo mode](/running-amp/solo-mode), `ampd solo` runs one, named
`worker`. In [distributed mode](/running-amp/distributed-mode), you run as many as you need, each with
`ampd worker --node-id`, and a name of your choice:

```bash
ampd worker --node-id worker-01
```

A node ID starts with a letter, and contains only letters, digits, `_`, `-`, and `.`. No two running workers can share
one.

Workers report to the metadata database every second. The controller only gives new jobs to active workers: those that
reported in the last five seconds.

### Which worker runs a job

The controller assigns each job to a worker when it schedules it:

1. The worker you name when you deploy, with `--worker-id`. It can be a pattern ending in `*`, like `eth-*`, to pick
   among workers whose names match.
2. Otherwise, the default worker, if the controller's configuration sets one.
3. Otherwise, an active worker, at random.

A job stays with its worker: its retries run there too, and a worker that restarts resumes its jobs. Adding workers
doesn't move existing jobs; it gives the controller more workers for new ones.

## Watching jobs and workers

* `ampctl dataset status` shows a deployment's status and each table's progress.
* `ampctl job` lists, inspects, and stops jobs, and shows their history. See [Jobs](/managing-amp/jobs).
* `ampctl worker` lists workers and when they last reported. See [Workers](/managing-amp/workers).
