---
title: "Run a workflow on a schedule - Workflow Suite"
description: "Start a workflow every few minutes, every hour, daily or weekly, in your store's time zone, with presets or your own cron expression."
canonical: "https://docs.workflow-suite.app/schedules"
---

# Schedules

The trigger **On a schedule** starts a workflow at the times you set, for example every morning at 8:00. Use it for reports, clean-up jobs, file imports and anything else that is not a reaction to one event.

## Set up a schedule

1. Select the trigger, **Change trigger**, and pick **On a schedule**.
2. Under **Runs**, pick a preset:
   - Every 5 minutes, Every 15 minutes, Every 30 minutes
   - Every hour, Every 6 hours
   - Daily at midnight, Daily at 09:00, Weekdays at 09:00
   - Weekly (Monday 09:00)
   - **Custom schedule**
3. For your own times, edit the **Cron expression**. The line under the field reads it back to you in words.
4. Choose the **Time zone**. It starts with your store's time zone, marked **(your store)**.
5. Save and turn the workflow on.

## Cron expressions

A cron expression has five fields: minute, hour, day of month, month, day of week.

| Expression | Runs |
| --- | --- |
| `0 8 * * *` | Every day at 08:00 |
| `30 6 * * 1-5` | Monday to Friday at 06:30 |
| `0 */2 * * *` | Every 2 hours, on the hour |
| `0 9 1 * *` | On the first day of every month at 09:00 |
| `*/10 * * * *` | Every 10 minutes |

The times are in the time zone you chose, so a daily 08:00 stays 08:00 when the clocks change. Schedules are checked once a minute.

## What the steps see

A scheduled run has no store event. Its steps usually begin by getting data:

- a Shopify query, for example the open orders older than three days. See [Every Shopify mutation and query](https://docs.workflow-suite.app/shopify-mutations-and-queries.md).
- a file from an SFTP server or a link. See [Files, SFTP and downloads](https://docs.workflow-suite.app/files-sftp-and-downloads.md).
- a value from the key-value store, for example the time of the last run.

Then a **Repeat for each** step works through the results. See [Repeat for each](https://docs.workflow-suite.app/repeat-for-each.md).

For the current date, Liquid's `now` works in every field:

```liquid
Daily report of {{ 'now' | date: '%Y-%m-%d' }}
```

> [!WARNING]
> **Plan large jobs in portions**
> A Shopify query step reads one page of results, and a Repeat for each handles up to 500 items. A scheduled job that must cover a whole large store should work in portions: search for what is still to do (for example products that still carry a tag), handle one page, and let the next run take the next page. The maintenance templates are built that way.

## Good to know

- Every scheduled run is a real run and counts against your plan. A job every 5 minutes is 8,640 runs in 30 days. See [Plans, runs and extra runs](https://docs.workflow-suite.app/plans-runs-and-extra-runs.md).
- A trigger filter is of little use on a schedule, because there is no event to filter on. To skip a run, start with a Condition.
- **Run now** in the editor starts the workflow once, outside its schedule. It is shown when the workflow is on and saved.
- To try a schedule without waiting, use **Test**.

## Related

- [Recipe: nightly cleanup with Repeat for each](https://docs.workflow-suite.app/recipe-archive-completed-orders.md)
- [Recipe: email a daily file from SFTP](https://docs.workflow-suite.app/recipe-email-daily-file-from-sftp.md)
