Skip to content

Scheduling overview

Saved flows can run on a recurring timer. Scheduling is a cross-edition platform feature: the schedule store, the recurrence engine, and the background scheduler are part of the shared Rust core, so the same schedule works whether the host is Flow Studio, a Flow Server instance, or a terminal running the CLI daemon.

  • A saved flow carries at most one schedule, keyed by its saved-template slug and persisted in the shared SQLite store. The desktop, the server, and the CLI all read and write the same schedules.
  • A schedule combines a cadence (presets, cron, fixed interval, or one-shot), an anchor instant, an IANA timezone, optional end conditions, and a catch-up policy for missed windows. See cadences and catch-up.
  • Every schedule is previewable before you commit: the picker shows the next firings so a cron expression never surprises you.

A configurable poll task asks the core for schedules whose next-run time has passed, then fires each due flow. The same loop runs in three places:

SurfaceHow it runs
Flow StudioSpawned by the desktop shell while the app is open
Flow ServerSpawned in the instance, so schedules fire with no browser attached
Flow CLIflow schedule daemon runs the loop on any host

Two properties make unattended firing safe:

  • No double-fire. The timer is advanced before the run, so an overlapping poll tick can’t fire the same window twice.
  • Honest unattended runs. Scheduled runs pass a per-run override that disables the interactive destructive-action confirmation gate, since there is no one to confirm. The persisted setting still governs interactive runs.

Scheduled runs execute on the same path as manual runs, so history and audit are uniform:

  • Each run persists to the same execution history and is tagged with a scheduled trigger, so you can filter for it in the History view.
  • The schedule tracks its run count and last status, shown wherever schedules surface.
  • A completion event broadcasts to the UI, so a finished scheduled run surfaces as a notification.
  • Inference for a scheduled run stays local: the zero-egress boundary is preserved, and only run metadata is recorded.