---
slug: agents/managing
title: Running and managing agents
kind: howto
surface: agents
summary: How to run an Aetherfy agent on demand with afy agents run, pause and resume its schedule, understand skipped and missed occurrences, and choose between stopping, archiving, and deleting an agent.
sources:
  - aetherfy-cli:cmd/agents.go
  - aetherfy-control-plane:api/routes/agents.py
  - aetherfy-control-plane:shared/job_runs.py
  - dashboard/src/lib/agents/agent-lifecycle.js
---

# Running and managing agents

## Running an Aetherfy agent on demand

Any deployed `type: job` agent on Aetherfy can be run on demand, whether or not
it has a schedule. This is the way to test a task before trusting it to a
cadence, and the way to re-process a window after a failure.

```bash
afy agents run nightly-report
```

Pass input as inline JSON, and block until the run finishes:

```bash
afy agents run nightly-report --payload '{"date":"2026-07-17"}' --wait
```

Or read the input from a file:

```bash
afy agents run nightly-report --payload-file ./input.json --wait
```

| Flag | Short | Effect |
|---|---|---|
| `--payload` | `-p` | Inline JSON input. Must be a JSON object. |
| `--payload-file` | `-f` | Read the JSON input from a file. Must be a JSON object. |
| `--wait` | — | Block until the run ends. Exits 0 on success, 1 on failure. |

`--payload` and `--payload-file` are mutually exclusive — pass one or neither,
never both.

Your code reads that input by fetching it from the Aetherfy API rather than
receiving it as an argument; see [/agents/task-contract](/agents/task-contract).

`--wait` exits 0 on success and 1 on failure, which makes `afy agents run` usable
directly as a CI step that fails the pipeline when the task fails. It stops
watching after **30 minutes**, but the run itself keeps going — check how it
ended with `afy agents runs nightly-report`.

A manual run on Aetherfy is entirely separate from the schedule. It does not
consume an occurrence, does not shift the next scheduled fire, and is not
recorded against the schedule.

Errors you can get back:

| Error | HTTP | Meaning |
|---|---|---|
| `AGENT_RUN_REQUIRES_JOB_TYPE` | 422 | The agent is not a `type: job` agent |
| `AGENT_NOT_DEPLOYED` | 422 | The agent has no deployment to run |
| `AGENT_RUN_INELIGIBLE_STATE` | 409 | The agent's current state does not permit a run |
| `AGENT_RUN_IN_PROGRESS` | 409 | A manual run is already in flight — Aetherfy allows one at a time per agent |

## Pausing and resuming an Aetherfy schedule

Pausing stops scheduled runs without touching `aetherfy.yaml` and without
redeploying. It is the right tool for a temporary stop — during an incident, a
migration, or a downstream outage.

```bash
afy agents schedule pause nightly-report
afy agents schedule resume nightly-report
```

| Behaviour | Detail |
|---|---|
| Idempotent | Pausing a paused schedule, or resuming a running one, is not an error |
| Manual runs still work | `afy agents run` is unaffected by a pause |
| No back-fill on resume | The next run is the next **future** occurrence |
| No schedule set | Both commands return 422 `AGENT_SCHEDULE_NOT_SET` |

The no-back-fill rule is the one to internalise. A schedule paused for a week
does **not** fire a week's worth of runs the moment you resume it — Aetherfy
picks up at the next future occurrence and the paused occurrences are simply
gone. If the work matters, run it manually to catch up.

There is **no** `afy agents schedule set` command on Aetherfy. Schedules are
declared in `aetherfy.yaml` and applied by deploying. To change the expression,
edit the file and deploy; to remove it entirely, deploy `schedule: null`. See
[/agents/scheduled-tasks](/agents/scheduled-tasks).

Note that deploying `schedule: null` clears any pause you had set along with the
schedule itself.

## Overlaps and missed windows on Aetherfy

Aetherfy **drops** occurrences that cannot run. It never queues them.

| Situation | What Aetherfy does |
|---|---|
| Overlap — the previous run is still in flight when the next is due | The due occurrence is **skipped**. Runs never stack up. |
| Missed window — the occurrence could not be evaluated within a 5-minute late-fire grace | It is recorded as **missed**, and the schedule moves to the next future occurrence. No catch-up burst. |

Both behaviours protect you from the classic failure where a task slows down,
occurrences pile up behind it, and the platform then executes all of them at
once against a system that is already struggling.

The trade-off is explicit: Aetherfy does not guarantee that every occurrence
runs. If you need that, a schedule is the wrong instrument — write the work into
a durable queue and let a task drain the queue on each fire. That way a skipped
fire costs you latency, not data.

## Last-fire badges on Aetherfy

Aetherfy records what happened at the most recent occurrence as a badge. A badge
describes **the fire**, not the outcome of the run it may have started.

| Badge | Meaning |
|---|---|
| FIRED | A run was started — check the run history for how it ended |
| SKIPPED | The previous run was still in flight, so this occurrence did not fire |
| MISSED | The occurrence could not fire — for example the late-fire window elapsed, or a plan limit blocked it |

Keep the two ideas separate: FIRED tells you Aetherfy started a run, and says
nothing about whether that run succeeded. For success or failure you want the
run history, at
[/agents/runs-and-logs](/agents/runs-and-logs).

Skipped and missed occurrences never create a run, so they cost nothing.

## How Aetherfy billing affects scheduled runs

When an account is over its usage limit, or has an unresolved payment issue,
Aetherfy records scheduled occurrences as **missed** instead of firing them.

Nothing is lost and nothing needs re-enabling afterwards. Raise the limit,
upgrade the plan, or settle the payment, and the next occurrence fires normally
on its own. Missed occurrences are not backfilled, so if the skipped work
matters, run it manually with `afy agents run`.

Manage all of this at
[https://app.aetherfy.com/dashboard/settings/billing](https://app.aetherfy.com/dashboard/settings/billing).

A schedule on Aetherfy adds no charge of its own. You pay for the compute the
runs actually consume.

## Stopping, archiving, and deleting an Aetherfy agent

These three act on the agent itself rather than on its schedule, and the
difference between them is what happens to your plan's quota.

| Command | What it does | Reversible with | Holds a quota slot |
|---|---|---|---|
| `afy agents stop <name>` | Pauses the agent — every machine stops and Aetherfy will not re-wake it on incoming traffic | `afy agents start <name>` | **Yes** |
| `afy agents archive <name>` | Destroys the underlying app to free the plan quota slot, while preserving the configuration and the stored code bundle | `afy agents restore <name>` | No |
| `afy agents delete <name>` | Removes the agent | — | No |

```bash
afy agents stop nightly-report
afy agents start nightly-report

afy agents archive nightly-report
afy agents restore nightly-report

afy agents delete nightly-report
```

Choose by intent. Stopping is for a short pause where you want the agent
instantly available again — but it still occupies a slot in your plan's agent
quota, so it does not help you deploy something else. Archiving is what frees
that slot; restoring is subject to a fresh plan-quota check at restore time, so
an archived agent is not guaranteed to come back if you have filled your quota
in the meantime.

To stop only the scheduled runs while leaving the agent deployed and reachable,
use `afy agents schedule pause` instead of any of these.
