Cron Triggers

Last updated Oct 17, 2026

Background

Cron Triggers allow users to map a cron expression to a Worker using a scheduled() handler that enables Workers to be executed on a schedule.

Cron Triggers are ideal for running periodic jobs, such as for maintenance or calling third-party APIs to collect up-to-date data. Workers scheduled by Cron Triggers will run on underutilized machines to make the best use of Cloudflare's capacity and route traffic efficiently.

Note

Cron Triggers are also available directly in Workflows via schedules on the Workflow binding instead. Refer to Trigger Workflows for details, and use a Wrangler release that supports Workflow schedules.

Cron Triggers execute on UTC time.

Add a Cron Trigger

1. Define a scheduled event listener

To respond to a Cron Trigger, you must add a "scheduled" handler to your Worker.

export default {
    async scheduled(controller, env, ctx) {
        console.log("cron processed");
    },
};
interface Env {}
export default {
    async scheduled(
        controller: ScheduledController,
        env: Env,
        ctx: ExecutionContext,
    ) {
        console.log("cron processed");
    },
};
from workers import WorkerEntrypoint

class Default(WorkerEntrypoint):
    async def scheduled(self, controller, env, ctx):
        # All four parameters (self, controller, env, ctx) are required
        print("cron processed")

Refer to the following additional examples to write your code:

2. Update configuration

Cron Trigger changes take time to propagate.

Changes such as adding a new Cron Trigger, updating an old Cron Trigger, or deleting a Cron Trigger may take several minutes (up to 15 minutes) to propagate to the Cloudflare global network.

After you have updated your Worker code to include a "scheduled" event, you must update your Worker project configuration.

Via cloudflare.config.ts

For projects managed with the Cloudflare CLI, add triggers.scheduled() entries to worker.triggers in cloudflare.config.ts:

Select a highlighted line to show its type and description below it.

cloudflare.config.ts

Expand allCopy

import { defineConfig, triggers } from "cf/config";

import * as entrypoint from "./src/index.ts" with { type: "cf-worker" };

<details>

<summary>export default defineConfig({ (defineConfig reference)</summary>

<code>defineConfig</code>Function<a href="#cron-triggers-config-defineconfig">Link to defineConfig</a>

<code>defineConfig<T extends ConfigInput<CloudflareConfig>>(config: T): T;</code>

Defines the default export of <code>cloudflare.config.ts</code>. Pass a configuration object, a promise that resolves to one, or a function that receives the config context (<code>isPreview</code> and <code>mode</code>) and returns either.

<details>

<summary>Options (4)</summary>

<dl>

<dt><code>accountId?: string</code></dt> <dd>This is the ID of the account associated with your zone. It can also be specified through the <code>CLOUDFLARE_ACCOUNT_ID</code> environment variable.</dd>

<dt><code>complianceRegion?: "public" | "fedramp-high"</code></dt> <dd>The compliance boundary in which commands should operate. When omitted, this can be supplied through <code>CLOUDFLARE_COMPLIANCE_REGION</code>.</dd>

<dt><code>worker?: ConfigInput<WorkerConfig></code></dt> <dd>The Worker defined by this configuration.</dd>

<dt><code>containers?: ConfigInput<ContainerConfig>[]</code></dt> <dd>Container applications defined by this configuration.</dd></dl></details>

</details>

<details>

<summary>worker: { (worker reference)</summary>

<code>worker</code>Optional<a href="#cron-triggers-config-cloudflareconfig-worker">Link to worker</a>

<code>worker?: ConfigInput<WorkerConfig></code>

The Worker defined by this configuration.

</details>

<details>

<summary>name: "my-worker", (name reference)</summary>

<code>name</code>Required<a href="#cron-triggers-config-workerconfig-name">Link to name</a>

<code>name: string</code>

The name of your Worker.

</details>

<details>

<summary>entrypoint, (entrypoint reference)</summary>

<code>entrypoint</code>Optional<a href="#cron-triggers-config-workerconfig-entrypoint">Link to entrypoint</a>

<code>entrypoint?: string | WorkerModule</code>

The entrypoint module that will be executed. May be either a path string (e.g. <code>"./src/index.ts"</code>) or a module namespace imported with the <code>cf-worker</code> import attribute.

</details>

<details>

<summary>compatibilityDate: "<COMPATIBILITY_DATE>", (compatibilityDate reference)</summary>

<code>compatibilityDate</code>Required<a href="#cron-triggers-config-workerconfig-compatibilitydate">Link to compatibilityDate</a>

<code>compatibilityDate: string</code>

A date in the form yyyy-mm-dd, which will be used to determine which version of the Workers runtime is used. More details at <a href="https://developers.cloudflare.com/workers/configuration/compatibility-dates">https://developers.cloudflare.com/workers/configuration/compatibility-dates</a>

</details>

<details>

<summary>triggers: [triggers.scheduled({ schedule: "0 * * * *" })], (triggers, scheduled, schedule reference)</summary>

<code>triggers</code>Optional<a href="#cron-triggers-config-workerconfig-triggers">Link to triggers</a>

<code>triggers?: Trigger[]</code>

Event triggers — fetch routes, queue consumers, cron schedules, Email Routing addresses, and raw sockets — that invoke this Worker. Construct entries with <code>triggers.fetch(...)</code>, <code>triggers.queue(...)</code>, <code>triggers.scheduled(...)</code>, <code>triggers.email(...)</code>, or <code>triggers.connect(...)</code>. For reference, see <a href="https://developers.cloudflare.com/workers/wrangler/configuration/#triggers">https://developers.cloudflare.com/workers/wrangler/configuration/#triggers</a>

<code>scheduled</code>Builder<a href="#cron-triggers-config-workerconfig-triggers">Link to scheduled</a>

<code>scheduled(options: ScheduledTriggerOptions): ScheduledTrigger;</code>

Scheduled (cron) trigger — invokes this Worker on the given schedules. More details here <a href="https://developers.cloudflare.com/workers/platform/cron-triggers">https://developers.cloudflare.com/workers/platform/cron-triggers</a>

<details>

<summary>Options (1)</summary>

<dl>

<dt><code>schedule: string</code></dt> <dd>A "cron" definition to trigger a Worker's "scheduled" function. Lets you call Workers periodically, much like a cron job. More details here <a href="https://developers.cloudflare.com/workers/platform/cron-triggers">https://developers.cloudflare.com/workers/platform/cron-triggers</a></dd>

</dl></details>

<code>schedule</code>Required<a href="#cron-triggers-config-workerconfig-triggers">Link to schedule</a>

<code>schedule: string</code>

A "cron" definition to trigger a Worker's "scheduled" function. Lets you call Workers periodically, much like a cron job. More details here <a href="https://developers.cloudflare.com/workers/platform/cron-triggers">https://developers.cloudflare.com/workers/platform/cron-triggers</a>

</details>

},

});

Run cf dev to test the handler locally. Run cf deploy to deploy the configured schedule.

Via the Wrangler configuration file

If a Worker is managed with Wrangler, Cron Triggers should be exclusively managed through the Wrangler configuration file.

Refer to the example below for a Cron Triggers configuration:

{
    "triggers": {
        // Schedule cron triggers:
        // - At every 3rd minute
        // - At 15:00 (UTC) on first day of the month
        // - At 23:59 (UTC) on the last weekday of the month
        "crons": [
            "*/3 * * * *",
            "0 15 1 * *",
            "59 23 LW * *"
        ]
    }
}
[triggers]
crons = [ "*/3 * * * *", "0 15 1 * *", "59 23 LW * *" ]

You also can set a different Cron Trigger for each environment in your Wrangler configuration file. You need to put the triggers array under your chosen environment. For example:

{
    "env": {
        "dev": {
            "triggers": {
                "crons": [
                    "0 * * * *"
                ]
            }
        }
    }
}
[env.dev.triggers]
crons = [ "0 * * * *" ]

Via the dashboard

To add Cron Triggers in the Cloudflare dashboard:

  1. In the Cloudflare dashboard, go to the Workers & Pages page. Go to Workers & Pages ↗
  2. In Overview, select your Worker > Settings > Triggers > Cron Triggers.

Supported cron expressions

Cloudflare supports cron expressions with five fields, along with most Quartz scheduler ↗︎-like cron syntax extensions:

Field Values Characters
Minute 0-59 * , - /
Hours 0-23 * , - /
Days of Month 1-31 * , - / L W
Months 1-12, case-insensitive 3-letter abbreviations ("JAN", "aug", etc.) * , - /
Weekdays 1-7, case-insensitive 3-letter abbreviations ("MON", "fri", etc.) * , - / L #

Note

Days of the week go from 1 = Sunday to 7 = Saturday, which is different on some other cron systems (where 0 = Sunday and 6 = Saturday). To avoid ambiguity you may prefer to use the three-letter abbreviations (e.g. SUN rather than 1).

Examples

Some common time intervals that may be useful for setting up your Cron Trigger:

  • * * * * *
  • At every minute
  • */30 * * * *
  • At every 30th minute
  • 45 * * * *
  • On the 45th minute of every hour
  • 0 17 * * sun or 0 17 * * 1
  • 17:00 (UTC) on Sunday
  • 10 7 * * mon-fri or 10 7 * * 2-6
  • 07:10 (UTC) on weekdays
  • 0 15 1 * *
  • 15:00 (UTC) on first day of the month
  • 0 18 * * 6L or 0 18 * * friL
  • 18:00 (UTC) on the last Friday of the month
  • 59 23 LW * *
  • 23:59 (UTC) on the last weekday of the month