Scheduling & Limits
An agent that only answers when spoken to needs neither of these blocks. One that wakes on its own needs both: schedule to decide when, and limits to decide how much it may consume once nobody is watching.
Scheduled Execution
schedule:
cron: '0 9 * * MON'
timezone: Europe/Paris
taskPrompt: Summarize last week's new tickets and post the digest.| Property | Description |
|---|---|
schedule.cron |
Standard 5-field cron expression (*/15 * * * *, 0 9 * * MON). |
schedule.timezone |
IANA identifier. Defaults to UTC. |
schedule.taskPrompt |
Required. Sent to the model as the user message on every run. |
Both cron and timezone are validated when the config is decoded, using the same parser as automation cron triggers. A malformed expression or an unknown zone fails sovrium validate offline — you find out at your desk, not from a job that never fired.
taskPrompt is the difference between a schedule and an alarm clock. The system prompt says who the agent is; the task prompt says what this particular run is for. Write it as an instruction with a definite end state — "summarize last week's new tickets and post the digest" — rather than an open remit like "check the tickets", which gives the model nothing to stop at.
Set timezone whenever the schedule means something to a person. 0 9 * * MON in the default UTC fires at 10 a.m. in Paris for half the year and 11 a.m. for the other half. A digest that lands before the working day starts is not a digest anyone reads. Zones handle daylight saving; a UTC offset baked into the cron expression does not.
Schedules are armed once the server has started and is accepting requests, and they are torn down on shutdown — so a restart leaves no timer firing an agent the new configuration no longer schedules.
What a Cron Run Passes Through
A cron run happens inside the server, on the timer you wrote, rather than arriving as a request from outside. That placement decides which of the agent's gates apply to it.
| Gate | On a cron run |
|---|---|
permissions.trigger |
Not applied. A timer is not an external caller, so an agent restricted to trigger: [admin] still runs on its own schedule. |
enabled: false |
Skipped. A disabled agent is never armed, so it never wakes the scheduler — the clean way to pause one without deleting config. |
| No AI provider configured | Skipped. A declared agent is inert without a model, and a run that reached no provider is not recorded as work the app has done. |
limits.maxConcurrentTasks |
Skipped when no slot is free. This is what stops a fast cron piling runs up behind a slow provider. |
limits.maxActionsPerMinute |
Not applied. The cron expression is the rate. |
limits.maxTokensPerDay |
Charged. The run's tokens count against the daily budget and appear in the agent's usage. |
approval |
Applied. mode: all on a nightly cron queues a request at 3 a.m. rather than executing, and it expires if timeout passes first. |
Triggering the Task by Hand
POST /api/agents/{name}/schedule/trigger runs the same taskPrompt on demand. That one is an external caller, and it passes every gate POST /api/agents/{name}/execute passes: the agent's permissions.trigger grant, where a refusal answers 404; 503 when the deployment has no AI provider; 202 with a queued status when maxActionsPerMinute or maxConcurrentTasks is exhausted; and 429 with a Retry-After header when the action rate limit trips. Its tokens are charged against maxTokensPerDay like any other run.
Operational Limits
limits caps consumption. Every field is optional and falls back to a system default.
| Property | Default | Caps |
|---|---|---|
limits.maxActionsPerMinute |
30 |
Database and email actions per minute. |
limits.maxTokensPerDay |
200000 |
LLM tokens per 24 hours. Resets at midnight UTC. |
limits.maxConcurrentTasks |
5 |
Simultaneous task executions. |
Each addresses a different failure, and the distinction matters when you choose values:
maxActionsPerMinutebounds a loop. An agent that misreads its own output and retries can hammer a table hundreds of times a minute; this is the ceiling that turns that into a slow anomaly instead of an outage.maxTokensPerDaybounds the bill. It is the only limit on this page with a direct cost in currency, and the only one you can reason about in advance — estimate a run's tokens, multiply by runs per day, add headroom.maxConcurrentTasksbounds contention. It matters most for agents triggered by users rather than cron, where ten people can invoke the same agent at once.
limits:
maxActionsPerMinute: 20
maxTokensPerDay: 150000
maxConcurrentTasks: 3The token budget resets at midnight UTC regardless of the agent's own timezone. An agent scheduled for 23:00 in Auckland is spending against a window that turns over mid-afternoon locally — worth knowing before a run mysteriously stops halfway through.
Sizing a Scheduled Agent
Work backwards from the cron. A daily agent that reads a hundred records and writes one summary might use twenty thousand tokens and thirty actions; maxTokensPerDay: 100000 then leaves room for a bad day without leaving room for a runaway one. An agent on */15 * * * * runs ninety-six times daily, so the same per-run cost needs a budget two orders of magnitude larger — and is usually a sign the schedule, not the budget, is the thing to reconsider.
Related Pages
- Agents Overview — the agent these blocks configure.
- Permissions & Approval — what happens when a scheduled run needs a human.
- Tools — the actions counted against
maxActionsPerMinute. - Automation Triggers — the same cron parser.
- AI Providers — the model whose tokens you are budgeting.
Last updated September 1, 2026
This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta. Contributions and corrections are welcome.