Skip to main content

Schedules

Windmill provides the same set of features as CRON, but with a user interface and control panels. It allows you to define Schedules for Scripts and Flows. Once a schedule is defined, the script will automatically run at the set frequency. Think of it as an easy-to-use scheduler similar to CRON that you can share with other users.

A Schedule consists of a Script or Flow, its arguments, a CRON expression that controls the execution frequency and optional Error and Recovery Handlers to deal with failed scheduled executions.


Cron is a powerful and versatile tool that enables users to automate tasks by scheduling them to run at specific intervals or times. From automating routine system maintenance to sending periodic email reports, cron plays an indispensable role in streamlining processes and improving productivity for developers, system administrators, and even casual users.

However, as with any powerful tool, using outside Windmill cron comes with its own set of challenges and potential issues. Common problems associated with the use of cron include:

  • Runs History: to maintain a record of script runs and log outputs through cron, you must manually incorporate that logic.
  • Error handling: in the event of a failed run, self-crafted logic is required for notifications (Slack, emails).
  • Manual Runs: executing a cron job manually, outside of its schedule, proves difficult and can lead to inconsistencies due to potential environment differences.
  • No UI: navigating cron jobs is challenging without a centralized hub, particularly for larger engineering teams. This comes with induced issues: 1. Handling permissions and Errors among users and editors and 2. Server downtime: when the server hosting the job experiences downtime, monitoring and alerting is problematic.

Windmill addresses these issues with schedules that can be defined with pre-set configuration for scripts and flows.

A bit of Context: How Windmill Works

Windmill is an open-source developer platform and infra to build all internal tools through code, such as UIs and workflows based on simple scripts (TypeScript, Python, Go, PHP, Bash, SQL and Rust).


Managing scripts, flows and apps on Windmill works at the workspace-level. Admins invite developers and operators to the workspace where are hosted workflows. The first two can write and edit flows as well as managing permissions, executions etc.


Cron jobs are one of many ways to trigger workflows in Windmill (among webhooks, auto-generated UIs, customized UIs, Command-line interface, Slackbots etc.)

Cron syntax

Windmill uses hexagons's croner expression parser. This library supports the Unix cron syntax as well as extensions allowing for more complex scheduling.

Although the syntaxes are similar, there are some notable differences:

FeatureUnix cronhexagon's croner library
Seconds FieldNot includedIncluded as the first field (optional)
Day of Week IndexSunday = 0 through Saturday = 6Sunday = 0 through Saturday = 6, or SUN through SAT
Month RepresentationNumeric and short namesNumeric, short names, and name ranges
List and Range in FieldsSupports lists and rangesSupports lists, ranges, and combinations
Step ValuesSupported (e.g., */2)Supported, including additional complex patterns like 4#2 etc.

Hexagon's croner expressions have the following additional modifiers:

  • ?: In croner a questionmark behaves just as *, to allow for legacy cron patterns to be used.
  • L: The letter 'L' can be used in the day of the month field to indicate the last day of the month. When used in the day of the week field in conjunction with the # character, it denotes the last specific weekday of the month. For example, 5#L represents the last Friday of the month.
  • #: The # character specifies the "nth" occurrence of a particular day within a month. For example, supplying 5#2 in the day of week field signifies the second Friday of the month. This can be combined with ranges and supports day names. For instance, MON-FRI#2 would match the Monday through Friday of the second week of the month.
  • W: The character 'W' is used to specify the closest weekday to a given day in the day of the month field. For example, 15W will match the closest weekday to the 15th of the month. If the specified day falls on a weekend (Saturday or Sunday), the pattern will match the closest weekday before or after that date. For instance, if the 15th is a Saturday, 15W will match the 14th (Friday), and if the 15th is a Sunday, it will match the 16th (Monday).
FieldRequiredAllowed valuesAllowed special charactersRemarks
SecondsOptional0-59* , - / ?
MinutesYes0-59* , - / ?
HoursYes0-23* , - / ?
Day of MonthYes1-31* , - / ? L W
MonthYes1-12 or JAN-DEC* , - / ?
Day of WeekYes0-7 or SUN-SAT* , - / ? # L0 to 6 are Sunday to Saturday
# is used to specify nth occurrence of a weekday

Some complex examples supported by the new syntax:

Schedule StringMeaning
0 0 */3 ? * *Every three hours
0 0 12 * * ?Every day at noon (12 PM)
0 0 12 * * MON-FRIEvery weekday at noon (12 PM)
0 0 12 15 * ?Every month on the 15th at noon (12 PM)
0 0 12 15W * ?Every month on the closest weekday to the 15th at noon (12 PM)
0 0 12 ? * 5#3Every third Friday of the month at noon (12 PM)
0 0 12 ? * 5LEvery last Friday of the month at noon (12 PM)
0 0 12 ? JAN,JUL,AUG *Every January, July, and August at noon (12 PM)
0 0 12 ? FEB-DEC/2 *Every other month from February to December at noon (12 PM)
0 0 12 1-15/2 * ?Every odd day from the 1st to the 15th of every month at noon (12 PM)

Anyway, the simplified builder and Windmill AI will help you to create the cron expression.

Migrating from legacy cron syntax

New schedules created in Windmill will use the new cron syntax.

If you have existing schedules using the legacy cron syntax, you can migrate them to the new syntax by following these steps:

  1. Go to the Schedules menu and select the schedule you want to edit.
  2. Toggle the enable latest Cron syntax
  3. Double check the preview for upcoming events and make sure it matches your expectations.
  4. Click on the Save button.

This will update the schedule to use the new cron syntax. Note, you will not be able to revert to the legacy syntax.


Migrate to croner

Set a schedule

Scripts and flows can have unique primary schedules and multiple other schedules.

Primary schedule

Each script and flow can have a primary schedule that can be configured from the script or flow settings.

There can only be one primary schedule per script or flow.

From the script settings, toggle on 'Schedule enabled' and Deploy the script.

Primary schedule

Other schedules

From your workspace, navigate to the dedicated Schedules menu and select New Schedule. You can also do that in the Other schedules section of a script.

There can be multiple other schedules per script.

Schedules menu

  1. Configure the schedule frequency using cron syntax, the simplified builder or a prompt with Windmill AI.

  2. Select a runnable (script or flow) from your workspace.

  3. Fill in the arguments that will be used for the automation. The arguments are the ones of the given script or flow. If you want your arguments to be dynamic, you might want to use a workflow.

  4. Optional: Add an Error handler.

  5. Optional: Add a Recovery Handler.

Note that modifying a script or flow that was previously scheduled will not un-schedule it and the said script or flow will run on its modified version after deployment.

Schedule a task

Click the Schedule button and you're good to go! The schedule will be automatically 'Enabled'. Toggle it off if needed.

Scheduled task

Handle Several Schedules for the Same Workflow

The previous configuration can be replicated multiple times for the same workflow and therefore several schedules can work in parallel.

If the Schedules menu allows you to control future executions of scripts and workflows, you can check all past and future runs clicking on Runs. This will lead you to the Runs menu, with a filtered view on your runnable.

Runs menu

... where you can get details on each run:

Run details

Configure schedules from flow editor

The same method can also be done from the flow editor.


From your workspace, pick the workflow you want to schedule.

Go to workflow

Go to the Schedule menu ...

Pick Schedule menu

and either schedule in cron or in Basic mode that will automatically be translated in cron. Once it's done, you can see in next picture that the cron expression is now visible on the toolbar.

Basic or cron schedule

Fill in the inputs, toggle the Schedule Enabled option, save, and you're all set!

Save and schedule

Schedule app reports

Send a PDF or PNG preview of any app at a given schedule.


More at:

Scheduled polls

A particular use case for schedules are Trigger scripts.

and have it return all of the new items since the last run as scheduled polls, without resorting to external webhooks.

Control permissions and errors

Schedule error handler

From the schedule configuration, add a special script or flow to execute in case of an error.

Schedule Error handler

For example, this can be a script that sends an error notification to Slack or Discord.

You can pick the Slack pre-set schedule error handler.


Schedule Error hander is an Enterprise Edition feature.

Schedule recovery handler

From the schedule configuration, add a special script or flow to execute in case of of recovery from Error.

You can pick the Slack pre-set schedule recovery handler.

Schedule Recovery Handler

Be notified every time a scheduled workflow has been executed

For scheduled flows, add a simple step to be notified about the execution of the scheduled flow.

In this example I chose to receive an email, but you can use other notification methods like Slack, Discord or any other other method your imagination and API calls can create.

Add an email step


Configure the email.

Configure email


And watch your mailbox.

Receive the email


Given how flows work on Windmill, it means that once the previous step has been successful, the Email step will trigger.

Error handler

If you want to handle failure and receive another message in that case, add an Error handler to your workflow that will let you know if a failure happened at any step.

Manage permissions from the workflow

From the settings menu, change the owner to a folder (group of people) to manage view and editing rights.

Manage permissions


The process is very simple but it will allow you to schedule tasks with confidence and get an aggregated view on them.

Not only can you build scheduled jobs from Windmill but also you can import all your existing scripts - as Windmill supports TypeScript, Python, Go, PHP, Bash or SQL - as did one of our esteemed users for their own scheduled jobs.

Failure to re-schedule

If a scheduled job fails to re-schedule, it will trigger a workspace error handler.

Schedule to run later

From a script or flow's page (after being deployed), you can "Schedule to run later" to schedule the execution to a given time without being recurring, therefore executing only once.

Go the the script or flow's page, click on the Advanced button, fill in the date and time, choose to "Override Worker group tag", or pick a specific worker group tag, and click on Run.

Schedule to run later