Scheduled tasks

A task agent normally runs when you trigger it. Give it a schedule: and Aetherfy runs it for you on a recurring cadence — no external cron box, no always-on machine burning money between runs. Each fire starts a fresh machine, runs your entrypoint once, and shuts down.

Adding a schedule

Add the field to your aetherfy.yaml and deploy. The schedule is validated at deploy time — a bad expression fails the deploy rather than silently never firing.

name: nightly-report
type: job
runtime: python
entrypoint: main.py

# 5 fields, UTC: minute hour day-of-month month day-of-week
schedule: "0 3 * * *"   # every day at 03:00 UTC

Expression format

Five whitespace-separated fields, always evaluated in UTC.

PositionFieldRange
1minute0–59
2hour0–23
3day of month1–31
4month1–12
5day of week0–6 (0 = Sunday)

One dialect, no variants: @hourly-style aliases and 6-field (seconds) syntax are rejected at deploy time. Write the five fields explicitly.

Examples

ExpressionFires
0 * * * *every hour, on the hour
*/15 * * * *every 15 minutes
0 3 * * *daily at 03:00 UTC
30 2 * * 1Mondays at 02:30 UTC
15 2 * * 1-5weekdays at 02:15 UTC

You do not have to write cron by hand. The dashboard configurator builds the expression from presets — hourly, daily, weekly, or a custom expression — and previews the next few runs in both UTC and your local time before you commit to it.

Minimum interval: 5 minutes

A schedule may not fire more often than once every 5 minutes. Deploys carrying * * * * * or */2 * * * * are rejected with an explanation.

An every-minute schedule is an always-on workload wearing a costume — it starts a machine 1,440 times a day. If your work is continuous or sub-5-minute, run an always-on agent (keep_alive) instead and let it loop internally.

Where a schedule is allowed

  • Only on type: job agents — a task that runs and exits. An always-on agent is already running; it has nothing to schedule.
  • One schedule per agent. To run the same code on two cadences, deploy it as two agents.
  • Not on workers spawned by a parent agent. A spawned worker is fired by its parent, not by the clock. Adding a schedule to one is rejected at deploy time.

Changing and removing a schedule

Your aetherfy.yaml is applied as a patch, so an unrelated re-deploy never disturbs a schedule you set earlier:

In the deployed yamlEffect
field omittedschedule preserved; the next run time does not move
same expressionno change; the next run time does not move
new expressionapplied; the next run time is recomputed from now
schedule: nullschedule removed; a pause you left on is cleared too
# Re-deploy without the field — the schedule is preserved
name: nightly-report
type: job

# ---

# Re-deploy with an explicit null — the schedule is removed
name: nightly-report
type: job
schedule: null

Removing a schedule does not delete the agent or its run history — it just stops firing. You can still run it on demand.

Time zones

Expressions are always interpreted in UTC. There is no time zone field, and deliberately so: a local-time schedule is ambiguous twice a year at daylight-saving boundaries — "every day at 02:30" can mean zero runs or two. UTC has no such edges, so 0 3 * * * means the same instant every day, forever.

The dashboard shows the expression with an explicit UTC label, and renders next-run and last-run timestamps in your local time with the zone named — so you always know which clock you are reading.