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 (or empty) required key raises
CronJobConfigError naming the index and the key. Entries are checked as they are started, in order, so validate your list up front: jobs for the entries before the bad one have already started and keep running on their daemon threads.
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 at its next interval rather than killing its scheduler thread. Without that, one agent raising once would silently take itself offline while the fleet appeared healthy.
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 — passblock=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. Running three agents at 1s, 2s and 3s for six seconds produces roughly 6, 3 and 2 executions.stop_many stops the jobs one after another, so a job can fit in one extra run while the ones before it shut down:
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 documentationRunnable Examples
The example files in the repository