Skip to content
Schedules & Exclusions

Schedules & Exclusions

Multi-Schedule Support

Pipelines can define multiple schedule windows per day. Each schedule has its own evaluation cycle, lock, run log entry, and SLA deadline.

schedules:
  - name: morning
    after: "06:00"
    deadline: "10:00"
    timezone: America/New_York
  - name: afternoon
    after: "14:00"
    deadline: "18:00"
    timezone: America/New_York

ScheduleConfig Fields

FieldTypeRequiredDescription
namestringyesUnique name within the pipeline (used as scheduleID)
afterstringnoHH:MM — schedule becomes active after this time
deadlinestringnoHH:MM — SLA deadline for this window
timezonestringnoIANA timezone (e.g. America/New_York); falls back to pipeline SLA timezone, then UTC

Default Schedule

Pipelines without an explicit schedules list get an implicit default:

schedules:
  - name: daily

The daily schedule has no after time (always active) and no per-schedule deadline (uses pipeline-level SLA if set).

How Schedules Work

During each watcher tick (or Step Function execution):

  1. ResolveSchedules() returns the configured schedules (or [{Name: "daily"}] if empty)
  2. For each schedule, IsScheduleActive() checks if now >= After in the schedule’s timezone
  3. A separate lock is acquired per schedule: eval:{pipelineID}:{scheduleID}
  4. Run logs are keyed by (pipelineID, date, scheduleID) — each schedule tracks independently
  5. SLA deadlines prefer the schedule’s deadline over the pipeline’s sla.evaluationDeadline

Hourly Schedules

For pipelines that run every hour, define 24 schedules:

schedules:
  - name: h00
    after: "00:00"
    deadline: "01:00"
  - name: h01
    after: "01:00"
    deadline: "02:00"
  # ... through h23

The dedup key becomes {pipeline}:{date}:{scheduleID} (e.g. my-pipeline:2026-02-23:h14).

SLA Configuration

SLAs enforce time-based constraints. Breaching an SLA fires an alert but does not cancel the pipeline.

sla:
  evaluationDeadline: "10:00"
  completionDeadline: "12:00"
  timezone: America/New_York
  validationTimeout: "+45m"

SLAConfig Fields

FieldTypeDescription
evaluationDeadlinestringHH:MM — all traits must reach READY by this time
completionDeadlinestringHH:MM — triggered job must finish by this time
timezonestringIANA timezone for deadline interpretation
validationTimeoutstringDuration offset (e.g. +45m) — hard stop for evaluation

Deadline Resolution

When a schedule defines its own deadline, that takes priority:

  1. Schedule deadlinesched.Deadline (if set)
  2. Pipeline evaluation SLAsla.evaluationDeadline (fallback)

The ParseSLADeadline() function converts an HH:MM string to an absolute time using the configured timezone and reference date.

Validation Timeout

Unlike SLA deadlines (which alert but continue), validationTimeout is a hard stop. If evaluation hasn’t completed within this offset from the schedule activation time, the Step Function transitions to a timeout state.

Calendar Exclusions

Pipelines can be excluded from running on specific days of the week or calendar dates. When excluded, the pipeline is completely dormant — no locks, no evaluation, no SLA alerts.

Inline Exclusions

exclusions:
  days:
    - saturday
    - sunday
  dates:
    - "2026-12-25"
    - "2026-01-01"

Named Calendar Reference

Define reusable calendars in YAML files:

# calendars/holidays.yaml
name: holidays
days:
  - saturday
  - sunday
dates:
  - "2026-12-25"
  - "2026-01-01"
  - "2026-07-04"

Reference from a pipeline:

exclusions:
  calendar: holidays

Combining Calendar + Inline

Inline days and dates are merged with the named calendar. A date or day matching any source triggers exclusion.

exclusions:
  calendar: holidays      # base exclusions
  days:
    - friday              # additional inline exclusion
  dates:
    - "2026-03-15"        # additional specific date

Calendar Configuration

Calendar YAML files are loaded from directories listed in calendarDirs:

calendarDirs:
  - ./calendars

Exclusion Evaluation

IsExcluded() checks in this order:

  1. Load the named calendar (if specified) from the registry
  2. Merge calendar days + dates with inline days + dates
  3. Resolve timezone from pipeline.SLA.Timezone (or UTC)
  4. Compare current day-of-week (case-insensitive) against merged days
  5. Compare current date (YYYY-MM-DD) against merged dates
  6. If any match → pipeline is excluded for today

Active runs from a previous day are picked up on the next non-excluded day or via callback API.