Schedules and cron
This page covers everything about controlling when an agent runs — the friendly options in the agent form, raw cron expressions, timezones, expiration, manual-only agents, and the org's minimum-interval rule.
Friendly schedule options
The agent form's Frequency dropdown offers ten options, each of which compiles to a standard five-field cron expression behind the scenes:
| Option | Cron equivalent |
|---|---|
| Manual only (no schedule) | _(none — schedule_cron is null)_ |
| Every N minutes | */{N} * * * * — N is any value from 1 to 59 |
| Every 15 minutes | */15 * * * * |
| Every 30 minutes | */30 * * * * |
| Every hour | {minute} * * * * |
| Every 6 hours | {minute} */6 * * * |
| Every day | {minute} {hour} * * * |
| Weekdays only | {minute} {hour} * * 1-5 |
| Specific days | {minute} {hour} * * {days} |
| Custom (advanced) | Whatever you type in the cron field. |
Where you see {hour}, {minute}, or {days}, those values come from the Hour / Minute / day-of-week pickers that appear conditionally based on the frequency you chose. Every N minutes shows its own minutes input (1–59); a platform floor of 5 minutes and your org's minimum-interval rule both apply, so a cadence under 5 minutes (or under a longer org interval) is rejected on save.
NoteOn a self-serve trial, the sub-hourly options are unavailable. A trial organization is clamped to a minimum of one hour between runs, so Every 15 minutes, Every 30 minutes and any Every N minutes value are rejected on save. The clamp lifts when the trial converts to a paid subscription.
Custom cron expressions
Expand Use a raw cron expression to override the friendly options with a five-field cron string:
┌───────────── minute (0–59)
│ ┌─────────── hour (0–23)
│ │ ┌───────── day of month (1–31)
│ │ │ ┌─────── month (1–12)
│ │ │ │ ┌───── day of week (0–6, Sunday = 0)
│ │ │ │ │
* * * * *
Examples Strata accepts:
0 9 * * 1-5— 09:00 every weekday.0 */2 * * *— every 2 hours on the hour.30 14 * * 0,6— 14:30 on weekends.0 9-17 * * 1-5— every hour 09:00 through 17:00, weekdays only (the "business hours" pattern used by the built-in SQL anomaly watcher template).
The expression is validated server-side with cron-parser. Anything it can't parse returns Invalid cron expression: <reason>. Empty or whitespace-only cron is also valid — it means "manual only, no schedule".
Timezones
Pick a timezone from the Timezone dropdown; type in its Search time zones field to narrow the list. The default is your timezone from Settings > General (or your browser's timezone if the setting hasn't been saved yet). Strata uses Intl.supportedValuesOf('timeZone') to populate the dropdown, so every IANA name is available.
The next-run timestamp is computed in the agent's timezone, not the org's or the server's. 0 9 * * 1-5 in America/New_York fires at 09:00 Eastern, which means a server in UTC sees it fire at 13:00 (or 14:00 during EDT).
Expiration date
Click Add an expiration date under the schedule sentence to bound how long the agent runs. Type a YYYY-MM-DD value or pick one from the calendar; backspace clears it. After this date, in the agent's own timezone, the scheduler stops picking the agent up and clears its next_run_at.
Reviving an expired agent. Clearing the expiration date, or moving it to a future date, brings the agent straight back: Strata recomputes the next run from its existing cron and the agent resumes on its normal cadence. You do not have to re-enter the schedule or redeploy.
Two details worth knowing:
- An agent that is paused (Active off) stays paused when you lift the expiry — reviving the schedule and resuming the agent are separate decisions.
- A manual-only agent has no cron to revive to. Lifting its expiry simply makes Run now and its webhook work again.
Manual Run now against an expired agent returns Agent has expired. Update or extend the expiration date to run it. (HTTP 400). Webhook triggers return Agent has expired.
Manual-only agents
Choose Manual only (no schedule) when you want an agent that only runs when you explicitly trigger it — from the Run now button or its webhook. Strata stores schedule_cron = null, which the scheduler poll skips entirely.
Manual agents appear on the Agents list with Manual in both the Schedule column and the Next column (not a dash). They count toward your Total stat and toward the org's Agents per member limit (max_agents_per_user), but never toward daily run caps unless you actually trigger them.
Use manual agents for:
- One-off tasks you want to keep around as repeatable building blocks.
- Webhook-driven workflows where the trigger is an external system.
- Tasks you only want to run after a teammate's review.
Platform floor and org-enforced minimum interval
Two limits stack when you save a schedule.
The platform floor — 5 minutes — applies to every organization, whether or not an admin has set anything. The scheduler polls once a minute, and this floor keeps an unattended agent from firing up to 1,440 times a day. Save a faster schedule and Strata returns:
Schedule is too frequent: scheduled agents run at most once every 5 minutes (this schedule fires every ~Ns). Pick a less frequent cadence.
On top of that, your admin can set a longer minimum interval (Minimum time between runs under Organization → Agents, set in minutes and stored as min_agent_interval_seconds). An admin can only make the interval longer than the platform floor, never shorter. When the admin's own value is the one in force, the message names them instead:
Schedule is too frequent: your organization requires at least Ns between runs (this schedule fires every ~Ms). Pick a less frequent cadence.
The check is run on both POST /api/agents and any PATCH that changes the cron. The estimator handles the common patterns (*, */N minute and hour fields); for more exotic expressions it doesn't second-guess you. Manual-only schedules are never blocked.
On a self-serve trial, a floor of 3,600 seconds (one hour) applies whether or not your admin set one. It is a clamp, not a replacement: if your admin's own minimum is longer, theirs still wins. Scheduled agents are the largest unattended cost in a trial — one agent on a five-minute cron fires roughly four thousand times over fourteen days — which is why the floor exists. Legacy indefinite-trial organizations are unaffected.
How the next run is computed
The scheduler polls once a minute. On every poll, the leader instance picks up agents whose next_run_at <= now, fires them, and immediately writes the new next_run_at for each one (computed from schedule_cron in the agent's timezone). Daylight-savings transitions are handled by the underlying cron-parser library — Strata doesn't reinvent that math.
If an agent has accumulated five consecutive failures, the scheduler backs it off rather than killing it: it defers the agent about an hour at a time, and once an hour has passed since the agent's last run it lets a single probe run through. The first probe that succeeds clears the failure streak and the agent returns to its normal cadence on its own — no edit or redeploy needed. A probe that fails backs it off for another hour, so a genuinely broken agent costs one short failing run per hour instead of running constantly. (See /docs/agents/permissions for what counts as a failure.)
If a run is throttled — the AI model is rate-limited or temporarily unavailable (an HTTP 429 or 503 from Azure AI Foundry) — Strata doesn't count it as a failure. Instead it defers that scheduled agent's next run by 15 minutes and retries, without consuming the agent's regular slot or incrementing its consecutive-failure count. Throttled runs are recorded in run history with a throttled status and never trigger a failure email.
Strata also defers a scheduled run by 15 minutes when it couldn't read the roles the owner's groups give them and, without those, the agent's model isn't allowed. It doesn't refuse the model on that partial answer: the run is recorded as not started, with Could not check which models this agent's owner may use. It will try again in 15 minutes. Only a scheduled run is deferred. Any other run ends Try again in a moment. instead, and Run now shows that under Could not start run. A model that really isn't allowed is different: that run fails with a message naming the setting that leaves the model out, and Strata pauses the agent, which shows Paused until you press Resume. See /docs/agents/permissions.
Run now
On the agent's detail page (or in the row actions on the Agents list), click Run now to fire the agent immediately, independent of its schedule. The run is recorded with trigger_type=manual. Run now works even on paused or manual-only agents. It is not exempt from your org's daily run cap, though — a manual run counts against the same per-user ceiling as a scheduled one. Once the cap is reached, Run now says so: You've reached your organization's limit of N agent runs per member per day. Runs start again at midnight UTC. If the agent's model is no longer allowed for you, Run now is refused: the page shows Could not start run with the reason instead of Run started, the run is recorded as failed (without counting toward the back-off), and the agent is left as it was, not paused. Pressing it again within 24 hours doesn't post the same Inbox notice again.
Dry runs
A dry run (Test run on the Agents page) executes the agent's prompt with destructive tools (send_email, save_to_onedrive, run_python, write_jira, write_confluence, invoke_agent) stripped from the toolset. The AI sees an extra system-prompt line:
DRY RUN: Tools that send email, save files, run code, write to Jira or Confluence, or run other agents are disabled. For any such step, describe in writing what you would have done — do not pretend it succeeded.
Result lands in run history with trigger_type=manual-dry, shown as Test run. It doesn't change the agent's status or failure streak, but it counts toward the daily run cap. Use test runs to verify behavior before granting destructive permissions.
Start one from Test run in the ... menu of an agent's row or of its own page, or programmatically — POST /api/agents/:id/run?dry=1. (You can also pass dry: true in the request body.)
What can go wrong
Invalid cron expression: ...— your cron didn't parse. Check the five-field format and the value ranges.Schedule is too frequent: ...— see the platform-floor / minimum-interval section above. If the message says scheduled agents run at most once every 5 minutes, you hit the platform floor; if it says your organization requires..., your admin set a longer interval. Pick a less frequent cadence.Agent has expired. Update or extend the expiration date to run it.— manually triggering an expired agent. Edit the agent and push the expiration date out (or remove it).- The agent ran in the wrong timezone — verify the Timezone field on the schedule step. Strata uses the agent's own timezone for next-run calculations, regardless of org or server timezone.
- The agent didn't run when expected — five consecutive failures back it off by about an hour at a time, with one probe run allowed through per hour. Check the agent's recent runs and fix the underlying error (missing extension, expired credentials, bad cron); the next probe that succeeds clears the streak automatically. The
last_run_statuscolumn on the Agents list shows the most recent outcome. - A run shows
throttled— the AI model was rate-limited or briefly unavailable. This isn't an error and isn't counted against the agent; Strata defers the next scheduled run by 15 minutes and retries automatically. No action is needed unless throttling persists across many runs. - The agent shows Paused and you didn't pause it — its model is no longer allowed for you, and a scheduled, webhook or linked-agent run found it. Your Inbox notice (<name> stopped) names the setting that leaves the model out and lists the models you can switch to; once an admin allows the model for you there or you edit the agent to use an allowed model, press Resume. Until then Resume is refused (This agent can't resume. …).
Related
- /docs/agents/create — the agent form, its Schedule section in context.
- /docs/agents/webhooks — triggering manual agents from outside.
- /docs/admin/rate-limits — admin-side
min_agent_interval_secondsandmax_agents_per_user.