Skip to main content
Real monitoring is rarely one cadence. You want a price check every thirty seconds, an anomaly scan every ten minutes, and a digest once an hour. Three rhythms, one process. A CronJob binds one agent to one interval, so a fleet needs one job per agent. CronJob.run_many builds them, starts them together, and blocks once.

Overview

Three agents, three cadences

The schedule spec

Each entry is a mapping. A missing required key raises CronJobConfigError naming the index and the key, before anything starts.

Isolation is the point

Each job runs on its own scheduler thread, so the agents cannot interfere with each other. Give the flaky one a budget and leave the others alone:
This isolation depends on the failure model: a task that raises is logged and retried on the next tick rather than killing its scheduler thread. Without that, one agent raising once would silently take itself offline while the fleet appeared healthy.
If any job exhausts its budget, run_many raises CronJobExecutionError once blocking ends, naming which jobs gave up and why.

Not blocking

When the schedule is not the main thing your process does — a web server, a bot, a notebook — pass block=False. You get the jobs back and own the lifecycle.
stop_many continues past any job that fails to stop, so one stuck job cannot strand the rest.

Verifying cadence

Cadences are independent and accurate. Running three agents at 1s, 2s and 3s for six seconds produces roughly 6, 3 and 2 executions:
This runs without API keys, since Echo stands in for a real agent. Anything exposing run(task=...) works.

Next steps

Failure Handling

Error budgets and live monitoring in depth

CronJob Quickstart

Start with a single agent

CronJob Reference

Full run_many and stop_many documentation

Runnable Examples

The example files in the repository