Aegra supports scheduled runs via a background cron scheduler. Cron jobs are stored in PostgreSQL and fired by a polling loop that runs inside every server instance.Documentation Index
Fetch the complete documentation index at: https://docs.aegra.dev/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
Enable the scheduler (it is on by default):Per-user cap. A single user can own at most
CRON_MAX_PER_USER crons (default 100). Creating beyond the cap returns HTTP 429. Set CRON_MAX_PER_USER=0 to disable.Sub-minute schedules. 6-field (seconds-first) schedules like
*/30 * * * * * are rejected unless CRON_ALLOW_SECONDS_SCHEDULE=true. They multiply scheduler load and DB writes per minute.Creating a stateless cron
A stateless cron fires against a new thread on every occurrence:assistant_id for cron creation and resolves it to the default assistant for that graph at request time.
By default, each stateless cron run deletes its ephemeral thread after the run completes, including the immediate first run that is triggered when the cron is created.
The snippets below assume you are inside an
async def function with an initialized client.Thread cleanup for stateless crons
Stateless crons create a fresh thread for every execution. Control what happens to that thread after the run finishes withon_run_completed:
"delete"(default) deletes the ephemeral thread automatically after the run completes."keep"preserves the thread so you can inspect its state or runs later.
Creating a thread-bound cron
Bind a cron to a specific thread so every firing continues the same conversation:Cron expression format
Aegra uses croniter for schedule parsing.Standard 5-field format
| Expression | Meaning |
|---|---|
0 9 * * * | Every day at 09:00 |
*/15 * * * * | Every 15 minutes |
0 9 * * 1 | Every Monday at 09:00 |
0 0 1 * * | First day of every month at midnight |
Seconds-level 6-field format
Prefix the standard expression with a seconds field for sub-minute scheduling:Timezone support
By default schedules use UTC. Pass an IANA timezone name to fire in local time:When updating a cron’s schedule without changing its timezone, the existing timezone is preserved automatically.
Listing and searching
Updating a cron
schedule, enabled, input, config, metadata, timezone.
Disabling and re-enabling
enabled=False at creation. In that case the immediate first run is skipped and the response is the persisted Cron instead of a Run.
Deleting a cron
ON DELETE CASCADE).
Limitations
- Scheduled runs skip per-request auth handlers. Creating a cron runs the full auth chain (
crons.create→assistants.read→threads.read/search), but each scheduled firing executes as a background daemon under the cron owner’s identity and does not re-dispatch@auth.on(...)handlers. Put per-run authorization logic in the graph itself if it must apply to scheduled runs. - Cron metadata is not copied onto fired runs.
metadataset on a cron is stored on the cron record for search and filtering, but is not propagated to the runs the cron creates. - Delivery is at-least-once. Under a crash between firing and advancing the schedule, a run can fire more than once for a single occurrence. Make scheduled work idempotent.