Skip to content
Get started
Get started
Cron Jobs in Bun: Scheduled Background Tasks
View Markdown
guide · cron jobs

Work that runs on a clock.

Nightly reports, hourly cleanups, a health ping every thirty seconds. Schedules live in the selected persistent backend: beside jobs in SQLite, or transactionally coordinated across a PostgreSQL broker fleet. Memory-only mode does not survive a restart.

A scheduler is a named rule that keeps producing jobs on a queue. Create it once with upsertJobScheduler() and bunqueue fires the job on every tick, whether that tick comes from a cron pattern or a fixed interval. Scheduler IDs are global to the selected backend—not scoped by queue—and, in PostgreSQL mode, shared by every broker in the namespace. Use names such as reports:daily-report when several applications share a deployment.

Create a scheduler with upsertJobScheduler. It works in both embedded and TCP mode, in every SDK (Python: upsert_job_scheduler, Rust: upsert_job_scheduler, Go: UpsertJobScheduler, Elixir: upsert_scheduler), and calling it again with the same global ID replaces that scheduler definition instead of duplicating it. Reusing an ID with a different queue moves the definition to that queue.

import { Queue, Worker } from 'bunqueue/client';
const queue = new Queue('reports', { embedded: true });
// Every day at 9:00 AM
await queue.upsertJobScheduler(
'daily-report',
{
pattern: '0 9 * * *',
},
{
name: 'daily-report',
data: { type: 'sales' },
}
);
// A normal worker processes the scheduled jobs
new Worker(
'reports',
async (job) => {
console.log('Running report:', job.data.type);
},
{ embedded: true }
);

Or from the CLI, against a running server:

Terminal window
bunqueue cron add daily-report -q reports -d '{"type":"daily"}' -s "0 9 * * *"
bunqueue cron list
bunqueue cron delete daily-report
Job Schedulers from the QueueNamed repeatable schedules on the Queue object
Cron RecipesFixed intervals, timezones, repeat-after-completion
Cron ReferenceExpression syntax, every scheduler option, MCP