website/src/content/docs/actors/schedule.mdx
Rivet Actor schedules invoke actions on the same actor and survive sleep, restarts, upgrades, and crashes. Use one-shot schedules for delayed work, cron jobs for calendar-based work, and fixed intervals for frequent jobs.
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);
},
},
});
Actors do not need to stay awake 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.
Runs once after the given delay in milliseconds and returns the generated schedule ID.
const id = await c.schedule.after(5_000, "sendReminder", reminderId);
Runs once at a Unix timestamp in milliseconds.
const id = await c.schedule.at(Date.parse("2026-08-01T09:00:00Z"), "openSale", saleId);
const schedule = await c.schedule.get(id);
const pending = await c.schedule.list();
const cancelled = await c.schedule.cancel(id);
Cron jobs use standard five-field expressions. Names are unique per actor, and reusing a name updates the existing job. The timezone defaults to UTC.
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.
});
Fixed-interval jobs keep their cadence anchored to scheduled deadlines, so action runtime does not introduce drift. Names are unique per actor, and reusing a name updates the existing job. The minimum interval is 5 seconds.
await c.cron.every({
name: "presence-sweep",
interval: 15_000, // Minimum 5 seconds.
action: "sweepPresence",
args: [], // Optional.
maxHistory: 25, // Optional; defaults to 100. Set to 0 to disable.
});
Submitting a recurring job with an existing name updates it. Changing its cadence calculates a new next run, while changing only its action, arguments, or history settings preserves the existing cadence.
const job = await c.cron.get("daily-report");
const jobs = await c.cron.list();
const deleted = await c.cron.delete("daily-report");
const recent = await c.cron.history("daily-report", {
limit: 20, // Optional.
});
Each entry's result is running, ok, error, or skipped. Jobs retain 100 entries by default. Set maximum history to zero to disable and clear history, or choose up to 1,000 entries. An actor retains at most 10,000 history entries across all jobs.
When a schedule invokes an action, it appends a ScheduledFireInfo object after the configured action arguments.
import type { ScheduledFireInfo } from "rivetkit";
const reports = actor({
onCreate: async (c) => {
await c.cron.set({
name: "daily-report",
expression: "0 9 * * *",
action: "runReport",
args: ["sales"], // Optional.
});
},
actions: {
runReport: (
_c,
report: string,
fire: ScheduledFireInfo,
) => {
console.log(
report,
fire.kind,
fire.id,
fire.name,
fire.scheduledAt,
fire.firedAt,
);
},
},
});