Skip to content
AgentDock

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:

FieldNotes
NameShown in the table and in notifications
RunsA skill or The orchestrator
Skill targetThe skill, its arguments, an optional profile (defaults to the project's default profile), model, and output report or pr. See Skills
Orchestrator targetstart (begin a new round) or next (pick up the next queued issue), using the project's Orchestrator settings
CronA 5-field expression or a macro (below)
TimezoneAn IANA name such as Europe/Berlin. Defaults to your browser's timezone
If a run is missedSkip 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.

Examples
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 with interval_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.

PolicyWhat happens
Skip (default)One skipped firing is recorded. Nothing runs until the next scheduled time
Catch upThe 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:

ReasonTrigger
failingFive firings in a row failed
creator_not_authorizedIts creator is no longer an active operator (or admin) of the project
manualA 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

apps/api/.env
SCHEDULER_ENABLED=false

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

JobWhen
audit-verificationDaily, AUDIT_VERIFY_CRON (default 0 3 * * *): checks the audit hash chain
activity-retentionDaily at 04:30: removes activity items older than ACTIVITY_RETENTION_DAYS (180)
webhooks-retentionDaily at 04:45: removes webhook delivery logs older than 30 days
github-deliveries-retentionDaily at 04:50: removes GitHub App delivery records older than 14 days
schedules.settleEvery 15 seconds: settles finished runs
schedules.reconcileEvery 60 seconds: the reconciler above

Who can do what

ActionMinimum role
See schedules and firingsviewer of the project
Create, edit, enable, disable, delete, run nowoperator of the project
See all projects' schedules and system jobsadmin

Creating, changing and deleting schedules is audited. Individual firings are recorded in the firings list and in History, not in the audit log.

Next steps