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.
An agent’s name becomes the first part of its URL, so it has to be a valid DNS
label: lowercase letters, digits and hyphens only, no leading, trailing or
doubled hyphen, and at most 47 characters. That budget is a DNS label’s 63,
less the 7-character suffix Aetherfy appends and the 9-character prefix on
the agent’s origin hostname — the origin is the longer of the two names, so it
is the one that binds. A small set of names that read as
infrastructure — api, admin, login, www and similar — is reserved, and
so is any name beginning e2e-test-, which belongs to Aetherfy’s own test
suite. A reserved name is refused when the agent is created, naming the rule;
nothing is silently renamed, because the name you choose becomes the permanent
first part of the address. Renaming an agent does not change
its URL: the address is fixed when the agent first deploys and stays put, so an
integration pointing at it keeps working.
What Aetherfy expects of your code depends entirely on which of the two agent types you deploy, and the difference is described in the next two sections.
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 | Yes — each run is a request to its POST /aetherfy/run |
job | Runs once and exits | No | No | Yes — each run executes the entrypoint |
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. Either type can carry a schedule — see
/agents/scheduled-tasks.
What Aetherfy expects your code to export
The two types make opposite demands of your entrypoint, and this is the fact most worth reading before you write any code.
service | job | |
|---|---|---|
| How Aetherfy starts your code | Imports the entrypoint as a module | Executes the entrypoint as a script |
| What your entrypoint must export | app — a FastAPI application on the Python runtimes, an Express application on the Node and Bun runtimes | nothing |
| Who runs the HTTP server | Aetherfy, on port 8080 | nobody — there is no server |
Who answers GET /health | Aetherfy, in front of your app — a /health route of your own is never reached | nobody |
if __name__ == "__main__": | Never runs — the module is imported, not executed | Runs normally |
For a job agent there is genuinely no framework to adopt and no handler
signature to implement: Aetherfy runs your file top to bottom and reads its exit
code, which is the whole contract at
/agents/task-contract.
For a service agent the export is mandatory, and omitting it stops the
deploy: an entry point that does not load is never reported healthy, so the
deploy fails with your interpreter’s own error message as its reason rather
than producing an agent that answers an error to every request. The full
contract, with a working example, is at
/agents/quickstart.
The dockerfile runtime opts out of all of this: you supply the container, so
you own the server, the port and the health endpoint. See
/agents/dockerfile.
How Aetherfy shuts a service down
When Aetherfy stops a service machine — a redeploy, a stop, or a scale-down —
it sends SIGTERM to your server and every process it started, and the
machine has 120 seconds before SIGKILL. Your server gets all of that
window except the few seconds the platform keeps for itself after it — to kill
what is left, read your last output and flush your logs — which is 100
seconds with today’s settings. Anything still running when your server’s
share ends is sent SIGKILL, workers included. That window is for finishing
in-flight requests and closing connections cleanly.
Two things follow. A redeploy is a blue-green swap, so the replacement machine
is healthy before the old one is asked to stop, and requests already in flight
drain inside that window rather than being cut off. And you do not need to
install a signal handler to get it: the runtime Aetherfy injects handles
SIGTERM for you on every standard runtime. Processes your app starts receive
the same SIGTERM, and are killed with it when the window ends.
The 120 seconds is a service figure. A job agent gets a much shorter grace
period, because a task is expected to end on its own — see
/agents/task-contract.
The type is set in configuration, not chosen at deploy time:
name: nightly-report
runtime: python3.12
type: jobHow 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.
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; the command
surface for agents is catalogued at /cli/agents. To go from an
empty directory to a running agent in one sitting, follow
/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.
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, with no build step — unless that image is no longer available, in which case the run first rebuilds it from the agent’s stored source. |
| 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 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.
Anything an Aetherfy agent writes to the vector database is attributed automatically, through the API key Aetherfy injects, to that agent and to the version that wrote it: the deployment, or for a task the run. See attested authorship.
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 plan 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 and /platform/limits.
Map of the Aetherfy agents documentation
| Page | What it covers |
|---|---|
| /agents/quickstart | Get an API key, install nothing else, deploy a working agent, read its logs |
| /agents/aetherfy-yaml | Every configuration field, the merge-patch rules, archive limits, lockfile requirements |
| /agents/scheduled-tasks | The schedule: field, the 5-field UTC cron expression format, what Aetherfy rejects |
| /agents/task-contract | How your code runs and exits, how it reads its input payload, the at-most-once guarantee |
| /agents/managing | Running on demand, pausing and resuming a schedule, overlaps and missed windows |
| /agents/runs-and-logs | Run history, run and agent states, log retrieval flags and retention limits |
| /agents/metrics | What each compute figure counts, its source, and why activity is not a fleet count |
| /agents/secrets | Agent-scoped and workspace-scoped secrets, key rules, reserved names |
| /agents/github | Connecting the GitHub App, linking a repository, what a push does |
| /agents/rollback | Returning an agent to an earlier deployment without rebuilding |
| /examples/agent-with-memory | A worked example combining an agent with the Aetherfy vector database |