Skip to content
GitHub Get Started
Operating System

Cron Jobs

Schedule recurring work with cron expressions, running either a shell command (exec) or an agent session (session), with overlap modes (allow, skip, queue) and cronEvent streaming to monitor execution. Cron jobs keep the actor alive while a job runs; the actor can sleep between executions.

Run a shell command on a recurring schedule. Pass a custom id to make a job easier to manage and cancel later.

client.ts
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
// Schedule a cleanup script every hour
const { id } = await client.vm.getOrCreate("my-agent").scheduleCron({
schedule: "0 * * * *",
action: {
type: "exec",
command: "rm",
args: ["-rf", "/tmp/cache/*"],
},
});
console.log("Cron job ID:", id);

See Full Example

Create a recurring agent session that runs a prompt on a schedule.

client.ts
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
// Run an agent every day at 9 AM to check for issues
await client.vm.getOrCreate("my-agent").scheduleCron({
schedule: "0 9 * * *",
action: {
type: "session",
agentType: "pi",
prompt: "Review the logs in /home/user/logs/ and summarize any errors",
options: { cwd: "/home/user" },
},
});

See Full Example

Control what happens when a cron job triggers while a previous execution is still running.

ModeBehavior
"skip"Skip this trigger if the previous run is still active
"allow"Allow concurrent executions (default)
"queue"Queue this trigger and run it after the previous one finishes

Prefer "skip" for most jobs to avoid unbounded concurrency if a run takes longer than the interval. Use "queue" when every trigger must eventually execute.

client.ts
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
// Queue overlapping executions
await client.vm.getOrCreate("my-agent").scheduleCron({
schedule: "*/5 * * * *",
overlap: "queue",
action: {
type: "session",
agentType: "pi",
prompt: "Process the next batch of tasks",
},
});

See Full Example

Subscribe to the cronEvent event to track job execution. It is emitted whenever a cron job runs, carrying a single payload field:

  • data.event: A CronEvent describing the run.
const conn = handle.connect();
conn.on("cronEvent", (data) => {
// data is inferred: { event: CronEvent }
console.log("Cron event:", data.event);
});

Subscribe before scheduling so you do not miss early runs.

client.ts
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const handle = client.vm.getOrCreate("my-agent");
const conn = handle.connect();
conn.on("cronEvent", (data) => {
// data is inferred: { event: CronEvent }
console.log("Cron event:", data.event);
});
await handle.scheduleCron({
schedule: "*/1 * * * *",
action: { type: "exec", command: "echo", args: ["heartbeat"] },
});

See Full Example

client.ts
import { createClient } from "@rivet-dev/agentos/client";
import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });
const handle = client.vm.getOrCreate("my-agent");
// List all cron jobs
const jobs = await handle.listCronJobs();
for (const job of jobs) {
console.log(job.id, job.schedule);
}
// Cancel a specific job
await handle.cancelCronJob(jobs[0].id);

See Full Example

Schedule a recurring agent session to periodically check on a task. This is the core pattern behind OpenClaw, where an agent wakes up on a schedule to review progress, take action, and go back to sleep.

await handle.scheduleCron({
schedule: "*/30 * * * *",
overlap: "skip",
action: {
type: "session",
agentType: "pi",
prompt: "Check the status of open issues and take any necessary action",
},
});

See Full Example

The agent sleeps between executions and only consumes resources when the cron job fires.