---
slug: agents
title: Agent compute overview
kind: explanation
surface: agents
summary: Aetherfy agent compute runs your code either as a long-lived service or as a task that runs once and exits, deployed from the afy CLI or a linked GitHub repository and configured by a single aetherfy.yaml file.
sources:
  - aetherfy-control-plane:models/agent.py
  - aetherfy-control-plane:shared/config_parser.py
  - aetherfy-control-plane:api/routes/agents.py
  - aetherfy-cli:cmd/deploy.go
---

# Aetherfy agent compute

## What Aetherfy agent compute is

Aetherfy agent compute runs your code on managed machines. You bring a directory
containing your program and one configuration file; Aetherfy builds an image,
places machines in one or more regions, injects your secrets as environment
variables, and keeps a record of every version you deploy.

An **agent** is the compute primitive. An agent has a name, a runtime, a type,
resource configuration, and optionally a schedule and a link to a GitHub
repository. Agent names on Aetherfy are lowercase letters, digits, and hyphens
only, 1–64 characters — they must match `^[a-z0-9-]+$`.

There is no framework to adopt and no handler signature to implement. Aetherfy
executes your entrypoint file and observes what it does.

## The two Aetherfy agent types

Aetherfy has exactly two agent types, chosen with the `type` field in
`aetherfy.yaml`. The default is `service`.

| Type | Lifecycle | HTTP server | Health check | Scheduling |
|---|---|---|---|---|
| `service` | Long-lived, supervisor style | Yes — your program serves requests | Yes | Not applicable |
| `job` | Runs once and exits | No | No | Yes — this is the type used for scheduled tasks |

A `service` agent on Aetherfy is always-on in the supervisor sense: it gets a
health check, an idle watcher, and is auto-started when a request arrives. Use it
for anything that answers requests.

A `job` agent runs once and exits. It has no HTTP server, no health check, and no
exposed port. Every scheduled task on Aetherfy is a `job` agent — see
[/agents/scheduled-tasks](/agents/scheduled-tasks).

The type is set in configuration, not chosen at deploy time:

```yaml
name: nightly-report
runtime: python3.12
type: job
```

## How Aetherfy agents are configured

One file describes an Aetherfy agent: `aetherfy.yaml`, at the root of the code
you upload. It is required. Aetherfy also accepts the filenames `aetherfy.yml`,
`.aetherfy.yaml`, and `.aetherfy.yml`, in that priority order.

The file declares the runtime, the type, memory, the entrypoint, an optional
schedule, and an optional workspace. It is applied as an RFC 7396 merge patch, so
a field you omit keeps whatever value the agent already has rather than reverting
to a default. The complete field table and the merge-patch rules are on
[/agents/aetherfy-yaml](/agents/aetherfy-yaml).

Aetherfy supports these runtimes, and only these:

| Family | Values |
|---|---|
| Python | `python3.11`, `python3.12`, `python3.13` |
| Node | `node20`, `node22`, `node20-ts`, `node22-ts` |
| Bun | `bun` |
| Container | `dockerfile` |

`python` on its own is **not** a valid runtime on Aetherfy. Older published
examples showed `runtime: python`; that value fails the deploy. Write the full
version, for example `runtime: python3.12`.

The runtime is immutable once an agent exists. Changing it is rejected with
`RUNTIME_IMMUTABLE` (HTTP 422); to move an agent to a different runtime, delete
it and recreate it.

## Deploying to Aetherfy

Aetherfy offers two deploy paths, and they produce the same result.

| Path | How it starts | Best for |
|---|---|---|
| CLI | `afy deploy` uploads the current directory | Local development, CI steps, first deploy |
| GitHub | A push to the tracked branch triggers a deployment | Ongoing delivery from a repository |

The CLI binary is `afy`. Install it by following [/cli](/cli); the command
surface for agents is catalogued at [/cli/agents](/cli/agents). To go from an
empty directory to a running agent in one sitting, follow
[/agents/quickstart](/agents/quickstart).

The GitHub path uses an Aetherfy GitHub App. Once a repository is linked to an
agent, a push to the tracked branch makes Aetherfy clone the repository at the
pushed commit, re-parse `aetherfy.yaml`, and deploy. Setup is on
[/agents/github](/agents/github).

## Deployments, runs, and workspaces on Aetherfy

Three nouns carry most of the meaning in Aetherfy agent compute.

| Noun | What it is |
|---|---|
| Deployment | One version of an agent. Building an image produces a deployment. |
| Run | An ephemeral execution of a `job` agent. A run reuses the agent's existing image — there is no build step. |
| Workspace | A group of agents that share secrets and can discover each other. |

Every Aetherfy run carries a trigger source that records why it happened:

| `trigger_source` | Meaning |
|---|---|
| `cron` | Fired by the agent's schedule |
| `manual` | Started on demand, with `afy agents run` |
| `spawn` | Started by a parent agent |

An agent belongs to at most one workspace, and workspace names are immutable
after creation. Secrets set on a workspace are visible to every agent in it;
secrets set on an agent override workspace secrets with the same key. See
[/agents/secrets](/agents/secrets).

## Regions and plans for Aetherfy agents

Where an Aetherfy agent runs depends on your plan. The regions Aetherfy accepts
are `us-east-1`, `eu-central-1`, and `ap-southeast-1`.

| Plan | Regional behaviour |
|---|---|
| Free | Single region — fixed by the first resource you create |
| Starter | Single region — fixed by the first resource you create |
| Performance | Multi-region |
| Enterprise | Multi-region |

Multi-region placement begins at the tier named **Performance**. On Free and
Starter, an Aetherfy account operates in one region, and that region is decided
by the first resource you create rather than chosen per agent. Your plan also
bounds the memory an agent may request and whether it may stay always-on. See
[/platform/regions](/platform/regions) and [/platform/limits](/platform/limits).

## Map of the Aetherfy agents documentation

| Page | What it covers |
|---|---|
| [/agents/quickstart](/agents/quickstart) | Get an API key, install nothing else, deploy a working agent, read its logs |
| [/agents/aetherfy-yaml](/agents/aetherfy-yaml) | Every configuration field, the merge-patch rules, archive limits, lockfile requirements |
| [/agents/scheduled-tasks](/agents/scheduled-tasks) | The `schedule:` field, the 5-field UTC expression format, what Aetherfy rejects |
| [/agents/task-contract](/agents/task-contract) | How your code runs and exits, how it reads its input payload, the at-most-once guarantee |
| [/agents/managing](/agents/managing) | Running on demand, pausing and resuming a schedule, overlaps and missed windows |
| [/agents/runs-and-logs](/agents/runs-and-logs) | Run history, run and agent states, log retrieval flags and retention limits |
| [/agents/secrets](/agents/secrets) | Agent-scoped and workspace-scoped secrets, key rules, reserved names |
| [/agents/github](/agents/github) | Connecting the GitHub App, linking a repository, what a push does |
| [/agents/rollback](/agents/rollback) | Returning an agent to an earlier deployment without rebuilding |
| [/examples/agent-with-memory](/examples/agent-with-memory) | A worked example combining an agent with the Aetherfy vector database |
