---
title: "Worker"
description: "A credential that lets a machine you control claim work. Not a machine."
url: "https://saved.sh/docs/concepts/workers"
---

A **worker** is a credential, not a machine. Provisioning one creates an ID that backups point
at, and a token that a process uses to claim work.

Everything confusing about workers dissolves once that distinction is held.

## Consequences of it being a credential [#consequences-of-it-being-a-credential]

| Because it is a credential                |                                                          |
| ----------------------------------------- | -------------------------------------------------------- |
| Reinstalling, moving host, or changing IP | Changes nothing. Nothing re-registers                    |
| Rotating the token                        | Keeps the ID, so assigned backups keep working           |
| Deleting the worker                       | Is permanent, and leaves its backups with nowhere to run |
| Several processes sharing one token       | Is possible, and is a mistake                            |

<Callout type="warn">
  **Run one process per worker credential.** Several may share one and all poll the same queue,
  but a run's steps hand each other a path to a file on local disk. Split them across two
  machines and the second looks for a file that is not there. To scale, provision a second
  worker.
</Callout>

## What it is for [#what-it-is-for]

A worker exists so that **a `local` backup's credentials never leave your network**. It
connects to your sources, produces the dump, encrypts it, and uploads ciphertext. We schedule
it and record what it did.

```
your host                            us
dump ─► encrypt ─► checksum ─► upload ──► object storage
                                  └─ checksum, size, filename ──► our API
```

Cloud and manual backups need no worker.

## What the token authorizes [#what-the-token-authorizes]

Exactly two permissions:

| Permission          | Allows                                                     |
| ------------------- | ---------------------------------------------------------- |
| `artifacts:upload`  | Request a presigned upload URL for one of its own runs     |
| `artifacts:confirm` | Report the checksum, size and filename of what it uploaded |

It cannot read backup definitions, list artifacts, download anything, or manage workers,
including itself. On the orchestration side it is bound to one namespace and one queue, its
own.

<Callout>
  That narrowness is why a worker is safe to run on a machine you would not trust with an API
  key. The real risk on that host is the **config file**, which holds your source credentials.
  Protect the file, not just the token.
</Callout>

## Routing is per worker [#routing-is-per-worker]

A `local` backup must name a worker, and its runs go **only** to that worker's queue.

* If the worker is offline, runs queue until it returns. They are not redistributed, because
  no other machine has the credentials.
* Changing a backup's worker recreates its schedule, so it takes effect from the next fire.

## Presence [#presence]

How many processes are polling, and when each was last seen, is read live from the
connections rather than from a heartbeat we store.

<Callout type="warn">
  **Connected is trustworthy; disconnected lags.** A worker that died thirty seconds ago can
  still look present for a few minutes. Read it as "last seen", never as a definite red light.
</Callout>

An instance count above one usually means a second copy of the same config is running
somewhere, which is the mistake above.

## Token, not key [#token-not-key]

A worker's credential is called a **token**, never a key. "Key" is reserved for your PGP
encryption key, and two unrelated "keys" in one product is a support burden nobody needs.

| Word               | Means                                           |
| ------------------ | ----------------------------------------------- |
| Encryption **key** | Your PGP key pair. We hold the public half only |
| Worker **token**   | Authenticates a worker                          |
| **API key**        | Authenticates automation                        |

## Rotate, do not delete [#rotate-do-not-delete]

|                  | Rotate                          | Delete                         |
| ---------------- | ------------------------------- | ------------------------------ |
| Worker ID        | Unchanged                       | Gone                           |
| Assigned backups | Keep working                    | Have nowhere to run            |
| Use it for       | A leak, a rebuilt host, hygiene | A worker you are finished with |

Rotation is the answer to almost everything.

## Limits [#limits]

| Plan  | Workers per workspace |
| ----- | --------------------- |
| Trial | 1                     |
| Paid  | 10                    |

## Next [#next]

<Cards>
  <Card href="/docs/workers" title="Local worker" description="Installing and running the process." />

  <Card href="/docs/workers/local-backups" title="What stays local" description="Exactly which bytes cross the boundary." />

  <Card href="/docs/cli/workers" title="sctl worker" description="Provisioning and rotating." />
</Cards>
