# Scheduled Tasks

A `type: scheduled` service combines an ECS task definition with an EventBridge Scheduler schedule. It does not create a continuously running ECS service. Between runs, the dashboard reports it as healthy with the `SCHEDULED` status.

```yaml
services:
  nightly-report:
    type: scheduled
    command: ["bundle", "exec", "rake", "reports:nightly"]
    cpu: 512
    memory: 1024
    schedule:
      expression: cron(0 3 * * ? *)
      timezone: America/New_York
      # enabled: false          # PAUSED: schedule exists but does not fire
      # retries: 3              # retries of a failed *invocation*, not a non-zero exit
      # dead_letter: job-failures  # an sqs resource from the resources block
```

```bash
keel jobs list                # configured vs live state, and when each next runs (--json)
keel jobs run nightly-report  # fire one now, without waiting (--timeout, default 15m)
```

## Schedule syntax

`cron(...)`, `rate(...)`, and `at(...)` are EventBridge Scheduler syntax:

- Expressions use six fields, including a year field.
- Use `?` for the day-of-month or day-of-week field you are not specifying. For example, daily at 03:00 is `cron(0 3 * * ? *)`. Keel rejects five-field crontab expressions.
- Day-of-week uses 1–7, where 1 is Sunday. This differs from standard crontab numbering.
- `timezone` is an IANA name (validated against real tzdata), defaulting to UTC.

## Unsupported service fields

Keel rejects `port`, `health_check`, `desired_count`, and `autoscaling` for scheduled services because they do not create an ECS service. Deploy and rollback still operate on the task-definition family, and `keel exec` works while a task is running.

`retries` applies when the `RunTask` invocation fails, not when a task starts and exits with a non-zero status. Use `keel logs nightly-report` for application failures or configure `dead_letter` with an SQS resource.

## Statuses

- **`SCHEDULED`** — the schedule exists and is enabled. Keel treats the service as healthy between runs.
- **`PAUSED`** — the schedule exists but is disabled with `enabled: false`. Edit `keel.yml` to enable it.

Use `type: worker` for a process that should run continuously.
