
# Scheduling & Limits

An [agent](/en/docs/ai-agents) 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

```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](/en/docs/automation-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.

:::callout
**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.
:::

Two blocks interact with the schedule. A disabled agent (`enabled: false`) skips its runs entirely, which is the clean way to pause one without deleting the config. And [approval](/en/docs/agent-approvals) still applies — `mode: all` on a nightly cron queues a request at 3 a.m. rather than executing, and it expires unactioned if `timeout` passes before anyone arrives.

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

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

## Related Pages

- [Agents Overview](/en/docs/ai-agents) — the agent these blocks configure.
- [Permissions & Approval](/en/docs/agent-approvals) — what happens when a scheduled run needs a human.
- [Tools](/en/docs/agent-tools) — the actions counted against `maxActionsPerMinute`.
- [Automation Triggers](/en/docs/automation-triggers) — the same cron parser.
- [AI Providers](/en/docs/ai-providers) — the model whose tokens you are budgeting.
