|
| 1 | +--- |
| 2 | +last_modified: 2026-05-13 |
| 3 | +title: "Cron" |
| 4 | +description: "Schedule recurring tasks in Deno with the Deno.cron() runtime API, an unstable feature enabled via --unstable-cron." |
| 5 | +--- |
| 6 | + |
| 7 | +[`Deno.cron()`](/api/deno/~/Deno.cron) is a Deno runtime API for scheduling |
| 8 | +JavaScript or TypeScript code to run on a recurring schedule, expressed using |
| 9 | +[cron syntax](https://en.wikipedia.org/wiki/Cron#UNIX-like). It ships with Deno |
| 10 | +itself, so the same code that runs locally can be deployed without changes. |
| 11 | + |
| 12 | +[`Deno.cron`](/api/deno/~/Deno.cron) is currently an unstable API. To use it |
| 13 | +locally with `deno run`, enable the |
| 14 | +[`--unstable-cron`](/runtime/reference/cli/unstable_flags/#--unstable-cron) flag |
| 15 | +(or add `"cron"` to the |
| 16 | +[`unstable`](/runtime/fundamentals/configuration/#unstable-features) array in |
| 17 | +`deno.json`). |
| 18 | + |
| 19 | +```sh |
| 20 | +deno run --unstable-cron main.ts |
| 21 | +``` |
| 22 | + |
| 23 | +<a href="/api/deno/~/Deno.cron" class="docs-cta runtime-cta">Deno.cron API |
| 24 | +reference</a> |
| 25 | + |
| 26 | +## Defining a cron job |
| 27 | + |
| 28 | +[`Deno.cron()`](/api/deno/~/Deno.cron) takes a human-readable name, a schedule, |
| 29 | +and a handler function. The name identifies the cron job in logs, the schedule |
| 30 | +determines when the handler fires, and all times are in UTC. |
| 31 | + |
| 32 | +```ts |
| 33 | +Deno.cron("log-a-message", "* * * * *", () => { |
| 34 | + console.log("This runs once a minute."); |
| 35 | +}); |
| 36 | +``` |
| 37 | + |
| 38 | +The schedule can be a standard 5-field cron expression or a structured object: |
| 39 | + |
| 40 | +```ts |
| 41 | +Deno.cron("hourly-task", { hour: { every: 1 } }, () => { |
| 42 | + console.log("This runs once an hour."); |
| 43 | +}); |
| 44 | +``` |
| 45 | + |
| 46 | +Cron jobs must be registered at the top level of a module, before any server |
| 47 | +starts. Definitions nested inside request handlers, conditionals, or callbacks |
| 48 | +will not be picked up. |
| 49 | + |
| 50 | +## Retries and backoff |
| 51 | + |
| 52 | +By default, failed handler invocations are not retried. Pass a `backoffSchedule` |
| 53 | +(an array of millisecond delays) to retry on failure: |
| 54 | + |
| 55 | +```ts |
| 56 | +Deno.cron( |
| 57 | + "retry-example", |
| 58 | + "* * * * *", |
| 59 | + { backoffSchedule: [1000, 5000, 10000] }, |
| 60 | + () => { |
| 61 | + throw new Error("Will be retried up to three times."); |
| 62 | + }, |
| 63 | +); |
| 64 | +``` |
| 65 | + |
| 66 | +## Running cron jobs in production |
| 67 | + |
| 68 | +[`Deno.cron`](/api/deno/~/Deno.cron) keeps execution state in-memory in the Deno |
| 69 | +CLI, which means each process maintains its own independent set of cron tasks. |
| 70 | +For production workloads, [Deno Deploy](/deploy/reference/cron/) builds on top |
| 71 | +of this runtime API: it discovers your [`Deno.cron()`](/api/deno/~/Deno.cron) |
| 72 | +definitions at deployment time, schedules and invokes them, handles retries, and |
| 73 | +surfaces runs in a dashboard — so you don't need to keep a long-running process |
| 74 | +up yourself. |
0 commit comments