Using AgentDock
Schedules
Cron rules that run skills or orchestrator rounds.
A schedule is a cron rule on a project that runs a skill or an orchestrator round at fixed times: a security scan every night, a new round every weekday morning. Open Project → Schedules and click New schedule.
A firing sends exactly the runner command a person would send, so scheduled runs show up in History, carry tokens and cost, and obey budgets like any other run.
Create a schedule
The dialog asks for:
| Field | Notes |
|---|---|
| Name | Shown in the table and in notifications |
| Runs | A skill or The orchestrator |
| Skill target | The skill, its arguments, an optional profile (defaults to the project's default profile), model, and output report or pr. See Skills |
| Orchestrator target | start (begin a new round) or next (pick up the next queued issue), using the project's Orchestrator settings |
| Cron | A 5-field expression or a macro (below) |
| Timezone | An IANA name such as Europe/Berlin. Defaults to your browser's timezone |
| If a run is missed | Skip or Catch up (below) |
While you type the cron, the dialog shows a plain-English description and the next five run times.
Nothing else can be scheduled: no shell commands and no arbitrary runner commands.
Cron syntax
Standard 5-field cron: minute, hour, day of month, month, day of week.
0 3 * * * every day at 03:00
30 8 * * 1-5 weekdays at 08:30
0 */4 * * * every 4 hours, on the hour
@hourly same as 0 * * * *
@daily same as 0 0 * * *
@weekly same as 0 0 * * 0
@monthly same as 0 0 1 * *- Seconds (a 6th field) are rejected. A minute is the finest resolution.
- Two firings of one schedule must be at least 5 minutes apart.
* * * * *is refused withinterval_too_short. Agent runs are long and cost real money; a minute-level schedule is almost always a mistake.
Timezones and DST
Fire times are computed in the schedule's timezone and stored in UTC. On a daylight-saving change, a local time that is skipped does not fire that day, and a local time that repeats fires once.
Missed runs
A run counts as missed when it is more than 2 minutes late, for example because the API was down or the runner was offline.
| Policy | What happens |
|---|---|
| Skip (default) | One skipped firing is recorded. Nothing runs until the next scheduled time |
| Catch up | The schedule fires once for the newest missed time, if it is less than 24 hours old. Older missed times are recorded as skipped. There is never a burst of catch-up runs |
If the runner is offline when a firing is due, the firing fails with runner_offline. With Catch up, AgentDock retries that occurrence when the runner comes back, within the 24-hour cap.
A schedule never overlaps itself: if the previous run is still going, the new occurrence is recorded as skipped with "the previous run is still going". An orchestrator target that finds the orchestrator already running is recorded as already running, which is not an error.
Run now, enable, edit
Each row has Edit, Run now and Delete, and an Enabled toggle. Run now fires one occurrence immediately without moving the next scheduled time. The schedule sheet shows the next run, the missed-run policy, failures in a row and the latest firings with their status (running, succeeded, failed, skipped, already running).
Automatic disable
A schedule turns itself off, says why on its row and sheet, and sends a schedule.disabled notification to admins when:
| Reason | Trigger |
|---|---|
failing | Five firings in a row failed |
creator_not_authorized | Its creator is no longer an active operator (or admin) of the project |
manual | A person switched it off |
A schedule always fires with its creator's authority, checked at fire time. Schedules do not outlive the people who made them: if the creator loses access the schedule is disabled, and if the creator's account is deleted their schedules are deleted with it. Runs a schedule already started stay in History.
A stop budget that is used up refuses scheduled runs the same way it refuses manual ones. See Usage, cost and budgets.
How firing works
Schedules run on BullMQ on Redis. Each enabled schedule has one delayed job for its next occurrence, and any API instance can process it.
- PostgreSQL is the source of truth. The schedule row holds the next run time. A job only says "check schedule S for time T"; if the row no longer matches, the job does nothing. A duplicated or replayed job never sends a second command to the runner.
- A reconciler runs every 60 seconds (and at startup). It re-creates timers that are missing and removes timers that no longer match a schedule. If Redis is wiped, timers are rebuilt from PostgreSQL within a minute, and occurrences that fell due in the meantime follow the missed-run policy.
- If Redis is down, the API keeps serving and you can still edit schedules. Nothing fires until Redis returns.
Redis is used for these timers only. It needs maxmemory-policy noeviction, and AOF persistence is recommended. You do not need to back it up.
Turning the scheduler off
SCHEDULER_ENABLED=falseWith SCHEDULER_ENABLED=false the API runs no schedule worker and REDIS_URL is no longer required. Otherwise the API refuses to start without REDIS_URL. See Configuration reference.
System jobs
Admin → Schedules lists every project's schedules and, read-only, the API's own background jobs. The page shows times in UTC; the daily jobs run on the API server's clock.
| Job | When |
|---|---|
audit-verification | Daily, AUDIT_VERIFY_CRON (default 0 3 * * *): checks the audit hash chain |
activity-retention | Daily at 04:30: removes activity items older than ACTIVITY_RETENTION_DAYS (180) |
webhooks-retention | Daily at 04:45: removes webhook delivery logs older than 30 days |
github-deliveries-retention | Daily at 04:50: removes GitHub App delivery records older than 14 days |
schedules.settle | Every 15 seconds: settles finished runs |
schedules.reconcile | Every 60 seconds: the reconciler above |
Who can do what
| Action | Minimum role |
|---|---|
| See schedules and firings | viewer of the project |
| Create, edit, enable, disable, delete, run now | operator of the project |
| See all projects' schedules and system jobs | admin |
Creating, changing and deleting schedules is audited. Individual firings are recorded in the firings list and in History, not in the audit log.