Skip to content

Task Scheduling

Task Scheduling lets you run container agents automatically on a schedule, using cron expressions, fixed intervals, or single one-time executions. Scheduled tasks are independent of the Squad UI and run in the background even when the app is minimized to the system tray.

Container task execution in this version

The Container Tasks tab in Automations is hidden in this version until the container task executor is wired (CONTAINER_TASK_SCHEDULER_AVAILABLE). Existing container tasks remain visible in a read-only section on Automations so you can inspect their run history or delete them, and due tasks record a skipped (not run: no container executor) entry instead of reporting a false success.

Schedule Types

Type When it runs Example use case
Cron At specific times defined by a cron expression Daily report at 9 AM on weekdays
Interval Repeatedly, every N milliseconds Monitoring check every 5 minutes
Once Once at a specific ISO timestamp Run a migration at a scheduled maintenance window

Creating a Scheduled Task

In the App

The Container Tasks tab is hidden for now

The Automations page does not show the Container Tasks tab while the container task executor is being finished, so the steps below apply once it returns. Until then, manage container tasks through the Management API.

  1. Go to Automations > Container Tasks.

  2. Click New Container Task.

  3. Fill in the container task form:

    Field Description
    Name Human-readable label
    Prompt The task description/instructions for the agent
    Schedule Type Cron, Interval, or Once
    Cron Expression, Interval (milliseconds), or Run At Cron expression, interval in ms, or ISO timestamp, depending on the schedule type
    Group Folder Container group namespace to run in
    Context Mode Reuse the group session context (group) or Start fresh for each execution (isolated, the default)
    Timezone IANA timezone for the schedule, prefilled with your system's
    Catch up missed executions on startup When the app starts, run the executions it missed while it was closed
  4. Click Create.

The form has no image, timeout, or on/off fields. A new container task starts enabled: pause or resume it with Disable task or Enable task on its card. The task runs aigo-agent-runner:latest with a 300-second timeout unless you set containerConfig through the Management API, as below.

Via Management API

curl -X POST http://localhost:8001/api/v1/container/schedules \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Daily Summary",
    "groupFolder": "reporting",
    "prompt": "Summarize the key events from today and write a report to /workspace/reports/daily.md",
    "scheduleType": {
      "type": "cron",
      "value": "0 9 * * 1-5"
    },
    "containerConfig": {
      "timeoutSecs": 600
    },
    "contextMode": "isolated"
  }'

Cron Expressions

Backend.AI GO uses standard 5-field cron expressions:

┌───────── minute (0-59)
│ ┌───────── hour (0-23)
│ │ ┌───────── day of month (1-31)
│ │ │ ┌───────── month (1-12)
│ │ │ │ ┌───────── day of week (0-7, Sunday = 0 or 7)
│ │ │ │ │
* * * * *

Common Examples

Expression Schedule
0 9 * * 1-5 Weekdays at 9:00 AM
0 */4 * * * Every 4 hours
30 8 * * 0 Sundays at 8:30 AM
0 0 1 * * First day of every month at midnight
*/15 * * * * Every 15 minutes

Timezone

Cron schedules run in the task's Timezone, an IANA name such as Asia/Seoul. The form prefills your system's timezone; through the API the default is UTC. The host's TZ environment variable is passed into containers.

Interval Schedules

Interval schedules run every N milliseconds. The interval must be at least 10,000 ms (10 seconds).

# Run every 5 minutes (300,000 ms)
curl -X POST http://localhost:8001/api/v1/container/schedules \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Health Monitor",
    "groupFolder": "monitoring",
    "prompt": "Check system health and append a status line to /workspace/health.log",
    "scheduleType": {
      "type": "interval",
      "value": 300000
    }
  }'

Drift Prevention

The scheduler computes next_run from the scheduled time, not the actual execution time. This prevents schedule drift — if a task takes 30 seconds, the next run is still at the expected time, not 30 seconds later.

One-Time Schedules

One-time schedules run once at a specific UTC timestamp and are automatically marked as completed:

curl -X POST http://localhost:8001/api/v1/container/schedules \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Database Migration",
    "groupFolder": "maintenance",
    "prompt": "Run the database migration script in /workspace/scripts/migrate.sh",
    "scheduleType": {
      "type": "once",
      "value": "2026-04-01T02:00:00Z"
    },
    "containerConfig": {
      "timeoutSecs": 3600
    }
  }'

Context Modes

The context mode determines how the container session is managed between runs:

Mode Behavior Best for
isolated Fresh session for every run (default) Independent tasks, reporting
group Reuses the group session across runs Stateful workflows, monitoring

In isolated mode, each run starts with a clean .claude/ session directory. In group mode, the session persists between runs, so the agent retains conversation history and memory.

Managing Schedules

List Schedules

curl http://localhost:8001/api/v1/container/schedules

Get a Schedule

curl http://localhost:8001/api/v1/container/schedules/{id}

Update a Schedule

curl -X PUT http://localhost:8001/api/v1/container/schedules/{id} \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'

Delete a Schedule

curl -X DELETE http://localhost:8001/api/v1/container/schedules/{id}

Pause a Schedule

Click Disable task on the task's card in Automations > Container Tasks, or set enabled: false to pause a container task without deleting it:

curl -X PUT http://localhost:8001/api/v1/container/schedules/{id} \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'

Viewing Run Logs

Every container task run creates a run log entry.

In the App

  1. Go to Automations > Container Tasks.

  2. Click a container task's card to open its Run History.

Via Management API

curl "http://localhost:8001/api/v1/container/schedules/{id}/logs?limit=20"

Response:

[
  {
    "id": "run-abc123",
    "taskId": "sched-xyz789",
    "runAt": "2026-03-15T09:00:00Z",
    "durationMs": 135000,
    "status": "success",
    "result": "Report written to /workspace/reports/daily.md"
  }
]

Run Status Values

Status Description
running Currently executing
success Finished; result holds the output summary
failed The run failed or exceeded its timeout; error says why
skipped The task was due while no container executor was wired; result records not run: no container executor
cancelled The run was cancelled

Container Configuration for Schedules

Each container task can specify container-specific settings:

{
  "containerConfig": {
    "image": "aigo-agent-runner:latest",
    "timeoutSecs": 300,
    "env": ["MY_CUSTOM_VAR=value"]
  }
}
Field Default Description
image aigo-agent-runner:latest Container image to use
timeoutSecs 300 Max execution time in seconds (0 = unlimited)
env [] Additional environment variables

Environment Variables Security

Only non-sensitive environment variables should be passed in env. API keys and credentials should always go through the Credential Proxy.

Troubleshooting

Schedule does not run

  • Verify enabled is true on the container task (its card shows Active)
  • Check the scheduler tick interval — the scheduler checks every 15 seconds
  • Ensure the container runtime is available

Schedule runs but fails immediately

  • Check the run log's error and result
  • Verify the container image exists: Settings > Squad > Agent Runner Image
  • Review the audit log for mount or permission errors

Cron schedule fires at wrong time

  • Check the task's Timezone (the API default is UTC)
  • Use an online cron expression tester to validate your expression
  • Remember: cron runs in the task's timezone, and the host's TZ env var is passed into the container

Interval schedule drifts

  • The scheduler uses drift-prevention logic (next run = scheduled time, not actual execution time)
  • If drift is still observed, check for system clock changes or heavy system load