Skip to main content
View as Markdown

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

app.yaml
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.

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:

  • maxActionsPerMinute bounds 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.
  • maxTokensPerDay bounds 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.
  • maxConcurrentTasks bounds contention. It matters most for agents triggered by users rather than cron, where ten people can invoke the same agent at once.
app.yaml
limits:
  maxActionsPerMinute: 20
  maxTokensPerDay: 150000
  maxConcurrentTasks: 3

The 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.

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.

Built with Sovrium