website/src/content/posts/2026-07-20-introducing-cron-jobs-for-rivet-actors/page.mdx
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.
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.
Use c.cron.set with a standard five-field crontab expression. Add an IANA timezone when the schedule should follow local time.
await c.cron.set({
name: "daily-report",
expression: "0 9 * * *",
timezone: "America/Los_Angeles",
action: "runReport",
maxHistory: 20,
});
Use c.cron.every for jobs that repeat after a fixed interval.
await c.cron.every({
name: "refresh-cache",
interval: 60_000,
action: "refreshCache",
});
Use c.cron.history to inspect recent runs for a named job.
const runs = await c.cron.history("daily-report", { limit: 10 });
The existing c.schedule.at and c.schedule.after APIs run an action once at an exact timestamp or after a delay.
await c.schedule.at(Date.parse("2026-08-01T09:00:00Z"), "openSale", "summer");
await c.schedule.after(30_000, "sendReminder", "reminder-123");
View one-off and recurring jobs in the Rivet dashboard, including each action, schedule, next run, and last run.
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);
},
},
});
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);
},
},
});
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);
},
},
});