Project: Prefect (Orchestration & Management / Scheduling & Orchestration)
File: schedules.md

description: Prefect can schedule when to automatically create new flow runs based on your deployments. tags: flows flow runs deployments schedules scheduling cron RRule iCal search: boost: 2 Scheduling is one of the primary reasons for using an orchestrator such as Prefect. Prefect allows you to use schedules to automatically create new flow runs for deployments. Prefect Cloud can also schedule flow runs through event-driven . Schedules tell the Prefect API how to create new flow runs for you automatically on a specified cadence. You can add a schedule to any . The Prefect `Scheduler` service periodically reviews every deployment and creates new flow runs according to the schedule configured for the deployment. !!! tip "Support for multiple schedules" We are currently rolling out support for multiple schedules per deployment. You can now assign multiple schedules to deployments in the Prefect UI, the CLI via `prefect deployment schedule` commands, the `Deployment` class, and in YAML files. Support for multiple schedules in `flow.serve`, `flow.deploy`, `serve`, and with `prefect deploy` will arrive soon. Prefect supports several types of schedules that cover a wide range of use cases and offer a large degree of customization: is most appropriate for users who are already familiar with `cron` from previous use. is best suited for deployments that need to run at some consistent cadence that isn't related to absolute time. is best suited for deployments that rely on calendar logic for simple recurring schedules, irregular intervals, exclusions, or day-of-month adjustments. !!! tip "Schedules can be inactive" When you create or edit a schedule, you can set the `active` property to `False` in Python (or `false` in a YAML file) to deactivate the schedule. This is useful if you want to keep the schedule configuration but temporarily stop the schedule from creating new flow runs. A schedule may be specified with a pattern. Users may also provide a timezone to enforce DST behaviors. `Cron` uses to specify datetime iteration with a `cron`-like format. `Cron` properties include: | Property | Description | | -- | - | | cron | A valid `cron` string. (Required) | | dayor | Boolean indicating how `croniter` handles `day` and `dayof_week` entries. Default is `True`. | | timezone | String name of a time zone. (See the for valid time zones.) | The `dayor` property defaults to `True`, matching the behavior of `cron`. In this mode, if you specify a `day` (of the month) entry and a `dayofweek` entry, the schedule will run a flow on both the specified day of the month *and* on the specified day of the week. The "or" in `dayor` refers to the fact that the two entries are treated like an `OR` statement, so the schedule should include both, as in the SQL statement `SELECT * FROM employees WHERE firstname = 'Xing' OR lastname = 'Brookins';`. For example, with `day_or` set to `True`, the cron schedule ` 3 1 2` runs a flow every minute on the 3rd day of the month (whatever that is) and on Tuesday (the second day of the week) in January (the first month of the year). With `dayor` set to `False`, the `day` (of the month) and `dayofweek` entries are joined with the more restrictive `AND` operation, as in the SQL statement `SELECT * from employees WHERE firstname = 'Andrew' AND lastname =

For example, the same schedule, when `dayor` is `False`, runs a flow on every minute on the 3rd Tuesday in January. This behavior matches `fcron` instead of `cron`. !!! tip "Supported `croniter` features" While Prefect supports most features of `croniter` for creating `cron`-like schedules, we do not currently support "R" random or "H" hashed keyword expressions or the schedule jittering possible with those expressions. !!! info "Daylight saving time considerations" If the `timezone` is a DST-observing one, then the schedule will adjust itself appropriately. The `cron` rules for DST are based on schedule times, not intervals. This means that an hourly `cron` schedule fires on every new schedule hour, not every elapsed hour. For example, when clocks are set back, this results in a two-hour pause as the schedule will fire the first time 1am is reached and the first time 2am is reached, 120 minutes later. Longer schedules, such as one that fires at 9am every morning, will adjust for DST automatically. An `Interval` schedule creates new flow runs on a regular interval measured in seconds. Intervals are computed using an optional `anchor_date`. For example, here's how you can create a schedule for every 10 minutes in a YAML file: ```yaml schedule: interval: 600 timezone: America/Chicago ``` `Interval` properties include: | Property | Description | | -- | - | | interval | `datetime.timedelta` indicating the time between flow runs. (Required) | | anchordate | `datetime.datetime` indicating the starting or "anchor" date to begin the schedule. If no `anchordate` is supplied, the current UTC time is used. | | timezone | String name of a time zone, used to enforce localization behaviors like DST boundaries. (See the for valid time zones.) | Note that the `anchor_date` does not indicate a "start time" for the schedule, but rather a fixed point in time from which to compute intervals. If the anchor date is in the future, then schedule dates are computed by subtracting the `interval` from it. Note that in this example, we import the Python package for easy datetime manipulation. Pendulum isnt required, but its a useful tool for specifying dates. !!! info "Daylight saving time considerations" If the schedule's `anchor_date` or `timezone` are provided with a DST-observing timezone, then the schedule will adjust itself appropriately. Intervals greater than 24 hours will follow DST conventions, while intervals of less than 24 hours will follow UTC intervals. For example, an hourly schedule will fire every UTC hour, even across DST boundaries. When clocks are set back, this will result in two runs that appear to both be scheduled for 1am local time, even though they are an hour apart in UTC time. For longer intervals, like a daily schedule, the interval schedule will adjust for DST boundaries so that the clock-hour remains constant. This means that a daily schedule that always fires at 9am will observe DST and continue to fire at 9am in the local time zone. An `RRule` scheduling supports (RRules), which provide convenient syntax for creating repetitive schedules. Schedules can repeat on a frequency from yearly down to every minute. `RRule` uses the module to specify iCal recurrence rules. RRules are appropriate for any kind of calendar-date manipulation, including simple repetition, irregular intervals, exclusions, week day or day-of-month adjustments, and

RRules can represent complex logic like: The last weekday of each month The fourth Thursday of November Every other day of the week `RRule` properties include: | Property | Description | | -- | - | | rrule | String representation of an RRule schedule. See the for syntax. | | timezone | String name of a time zone. See the for valid time zones. | You may find it useful to use an RRule string generator such as the to help create valid RRules. For example, the following RRule schedule in a YAML file creates flow runs on Monday, Wednesday, and Friday until July 30, 2024. ```yaml schedule: rrule: 'FREQ=WEEKLY;BYDAY=MO,WE,FR;UNTIL=20240730T040000Z' ``` !!! info "RRule restrictions" Note the max supported character length of an `rrulestr` is 6500 characters Note that `COUNT` is not supported. Please use `UNTIL` or the `/deployments/{id}/runs` endpoint to schedule a fixed number of flow runs. !!! info "Daylight saving time considerations" Note that as a calendar-oriented standard, `RRules` are sensitive to the initial timezone provided. A 9am daily schedule with a DST-aware start date will maintain a local 9am time through DST boundaries. A 9am daily schedule with a UTC start date will maintain a 9am UTC time. There are several ways to create a schedule for a deployment: Through the Prefect UI Via the `cron`, `interval`, or `rrule` parameters if building your deployment via the of the `Flow` object or for managing multiple flows simultaneously If using When you define a deployment with `flow.serve` or `flow.deploy` Through the interactive `prefect deploy` command With the `deployments` -> `schedules` section of the `prefect.yaml` file If using - Deprecated `Through the schedules` section of the deployment YAML file By passing `schedules` into the `Deployment` class or `Deployment.buildfromflow` You can add schedules in the Schedules section on a Deployment page in the UI. The Schedules section appears in the sidebar on the right side of the page on wider displays. On narrower displays, it appears on the Details tab of the page. Under Schedules, select the + Schedule button. A modal dialog will open. Choose Interval or Cron to create a schedule. !!! note "What about RRule?" The UI does not support creating RRule schedules. However, the UI will display RRule schedules that you've created via the command line. The new schedule will appear on the Deployment page where you created it. In addition, the schedule will be viewable in human-friendly text in the list of deployments on the Deployments page. After you create a schedule, new scheduled flow runs will be visible in the Upcoming tab of the Deployment page where you created it. You can edit a schedule by selecting Edit from the three-dot menu next to a schedule on a Deployment page. When you create a deployment in a Python file with `flow.serve()`, `serve`, `flow.deploy()`, or `deploy` you can specify the schedule. Just add the keyword argument `cron`, `interval`, or `rrule`. ``` interval: An interval on which to execute the deployment. Accepts a number or a timedelta object to create a single schedule. If a number is given, it will be interpreted as seconds. Also accepts an iterable of numbers or timedelta to create multiple schedules. cron: A cron schedule string of when to execute runs of this deployment. Also accepts an iterable of cron schedule strings to create multiple schedules. rrule: An rrule schedule string of when to execute runs of this deployment. Also accepts an iterable of rrule schedule strings to create multiple schedules. schedules: A list of schedule objects defining when to execute runs of this deployment. Used to define multiple schedules or additional scheduling options such as

schedule: A schedule object defining when to execute runs of this deployment. Used to define additional scheduling options like `timezone`. ``` Here's an example of creating a cron schedule with `serve` for a deployment flow that will run every minute of every day: ```python my_flow.serve(name="flowing", cron=" *") ``` If using work pool-based deployments, the `deploy` method has the same schedule-based parameters. Here's an example of creating an interval schedule with `serve` for a deployment flow that will run every 10 minutes with an anchor date and a timezone: ```python from datetime import timedelta, datetime from prefect.client.schemas.schedules import IntervalSchedule myflow.serve(name="flowing", schedule=IntervalSchedule(interval=timedelta(minutes=10), anchordate=datetime(2023, 1, 1, 0, 0), timezone="America/Chicago")) ``` Block and agent-based deployments with Python files are not a recommended way to create deployments. However, if you are using that deployment creation method you can create a schedule by passing a `schedule` argument to the `Deployment.buildfromflow` method. Here's how you create the equivalent schedule in a Python deployment file. ```python from prefect.client.schemas.schedules import CronSchedule crondemo = Deployment.buildfrom_flow( pipeline, "etl", schedule=(CronSchedule(cron="0 0 *", timezone="America/Chicago")) ) ``` If you are using , you can create a schedule through the interactive `prefect deploy` command. You will be prompted to choose which type of schedule to create. If you save the `prefect.yaml` file from the `prefect deploy` command, you will see it has a `schedules` section for your deployment. Alternatively, you can create a `prefect.yaml` file from a recipe or from scratch and add a `schedules` section to it. ```yaml deployments: ... schedules: cron: "0 0 *" timezone: "America/Chicago" active: false cron: "0 12 *" timezone: "America/New_York" active: true cron: "0 18 *" timezone: "Europe/London" active: true ``` The `Scheduler` service is started automatically when `prefect server start` is run and it is a built-in service of Prefect Cloud. By default, the `Scheduler` service visits deployments on a 60-second loop, though recently-modified deployments will be visited more frequently. The `Scheduler` evaluates each deployment's schedules and creates new runs appropriately. For typical deployments, it will create the next three runs, though more runs will be scheduled if the next 3 would all start in the next hour. More specifically, the `Scheduler` tries to create the smallest number of runs that satisfy the following constraints, in order: No more than 100 runs will be scheduled. Runs will not be scheduled more than 100 days in the future. At least 3 runs will be scheduled. Runs will be scheduled until at least one hour in the future. These behaviors can all be adjusted through the relevant settings that can be viewed with the terminal command `prefect config view --show-defaults`: <div class='terminal'> ```bash PREFECTAPISERVICESSCHEDULERDEPLOYMENTBATCHSIZE='100' PREFECTAPISERVICESSCHEDULERENABLED='True' PREFECTAPISERVICESSCHEDULERINSERTBATCHSIZE='500' PREFECTAPISERVICESSCHEDULERLOOP_SECONDS='60.0' PREFECTAPISERVICESSCHEDULERMIN_RUNS='3' PREFECTAPISERVICESSCHEDULERMAX_RUNS='100' PREFECTAPISERVICESSCHEDULERMINSCHEDULEDTIME='1:00:00' PREFECTAPISERVICESSCHEDULERMAXSCHEDULEDTIME='100 days, 0:00:00' ``` </div> See the for more information on altering your settings. These settings mean that if a deployment has an hourly schedule, the default settings will create runs for the next 4 days (or 100 hours). If it has a weekly schedule, the default settings will maintain the next 14 runs (up to 100 days in the future). !!! tip "The `Scheduler` does not affect execution" The Prefect `Scheduler` service only creates new flow runs and places them in `Scheduled` states. It is not involved in flow or task execution. If you change a schedule, previously scheduled flow runs that have not started are removed, and new scheduled flow runs are created to reflect the new schedule. To remove all scheduled runs for a flow deployment, you can remove the schedule via the UI.