From faada3a05f850d50328333022c47a78b6632ab01 Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Mon, 20 Jul 2026 02:29:15 -0700 Subject: [PATCH] docs(website): explain sleeping schedules --- website/src/content/docs/actors/schedule.mdx | 8 ++- .../page.mdx | 70 ++++++++++++++++++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/website/src/content/docs/actors/schedule.mdx b/website/src/content/docs/actors/schedule.mdx index 1bf374f16b..0ec0b43d66 100644 --- a/website/src/content/docs/actors/schedule.mdx +++ b/website/src/content/docs/actors/schedule.mdx @@ -64,6 +64,12 @@ const cache = actor({ +## Sleep Between Runs + +[Actors do not need to stay awake](/docs/actors/lifecycle#sleeping) while waiting for a scheduled action. Once an actor becomes idle, it can sleep normally. Sleeping does not pause or remove its schedules. Rivet wakes the actor when the next action is due, whether that is seconds or arbitrarily far in the future. + +Recurring Cron and fixed-interval schedules continue until they are updated or deleted. One-shot schedules remain pending until their target time. + ## One-shot schedules ### Run after a delay @@ -178,7 +184,7 @@ const reports = actor({ ## Execution behavior -- **Durability**: [Actors sleep when not in use](/docs/actors/lifecycle#sleeping), but schedules are durable, wake the actor on demand, and survive crashes. +- **Durability**: Schedules survive actor sleep, restarts, upgrades, and crashes. See [Sleep Between Runs](#sleep-between-runs). - **Failures**: Failed runs are not retried immediately. A failed recurring run continues at the next normal cadence; a failed one-shot is complete after its attempted invocation. Cron failures are available in [run history](#view-run-history), so you can build a custom retry mechanism. - **Idempotency**: Scheduled actions should be idempotent so manually retrying a failed or interrupted run is safe. - **Overlaps**: Overlapping recurring runs are skipped. diff --git a/website/src/content/posts/2026-07-20-introducing-cron-jobs-for-rivet-actors/page.mdx b/website/src/content/posts/2026-07-20-introducing-cron-jobs-for-rivet-actors/page.mdx index 3e98ef44ae..ffb8c8813b 100644 --- a/website/src/content/posts/2026-07-20-introducing-cron-jobs-for-rivet-actors/page.mdx +++ b/website/src/content/posts/2026-07-20-introducing-cron-jobs-for-rivet-actors/page.mdx @@ -6,11 +6,15 @@ image: true keywords: ["cron", "scheduled jobs", "actors", "durable", "timezone", "typescript"] title: "Introducing Durable Cron Jobs for Rivet Actors" -description: "Durable, timezone-aware Cron jobs that wake actors on schedule and survive sleep, restarts, deploys, and crashes." +description: "Durable, timezone-aware Cron jobs that let actors sleep between executions and wake on schedule indefinitely." --- Cron jobs are now built into Rivet Actors. Schedules wake actors on demand and survive sleep, restarts, deploys, and crashes. Use standard five-field expressions with an optional timezone, and inspect recent runs from the Rivet Inspector. +## Sleep Between Runs + +Actors do not need to stay awake while waiting for their next run. After an action finishes and the actor becomes idle, it can sleep normally. Rivet wakes it when the next action is due, even when that run is arbitrarily far in the future. Recurring schedules continue indefinitely until they are updated or deleted. + ## Schedule with Crontab and a Timezone Use `c.cron.set` with a standard five-field crontab expression. Add an IANA timezone when the schedule should follow local time. @@ -54,6 +58,70 @@ await c.schedule.at(Date.parse("2026-08-01T09:00:00Z"), "openSale", "summer"); await c.schedule.after(30_000, "sendReminder", "reminder-123"); ``` +## Inspect Schedules in the Dashboard + +View one-off and recurring jobs in the Rivet dashboard, including each action, schedule, next run, and last run. + +![Rivet dashboard showing one-off and recurring actor schedules](https://assets.rivet.dev/website/blog/2026-07-20-introducing-cron-jobs-for-rivet-actors/dashboard-schedules.png) + +## Full Actor Examples + + + +```ts After +const reminders = actor({ + onCreate: async (c) => { + await c.schedule.after(30_000, "sendReminder", "reminder-123"); + }, + actions: { + sendReminder: (_c, reminderId: string) => { + console.log("Sending reminder", reminderId); + }, + }, +}); +``` + +```ts Cron +const reports = actor({ + onCreate: async (c) => { + await c.cron.set({ + name: "daily-report", + expression: "0 9 * * *", + action: "runReport", + args: ["sales"], // Optional. + timezone: "America/Los_Angeles", // Optional; defaults to UTC. + maxHistory: 100, // Optional; defaults to 100. Set to 0 to disable. + }); + }, + actions: { + runReport: (_c, report: string) => { + console.log("Running report", report); + }, + }, +}); +``` + +```ts Every +const cache = actor({ + onCreate: async (c) => { + await c.cron.every({ + name: "refresh-cache", + interval: 60_000, // Minimum 5 seconds. + action: "refreshCache", + args: ["products"], // Optional. + maxHistory: 100, // Optional; defaults to 100. Set to 0 to disable. + }); + }, + actions: { + refreshCache: (_c, cache: string) => { + console.log("Refreshing cache", cache); + }, + }, +}); +``` + + + ## More Links - [Schedule & Cron documentation](/docs/actors/schedule)