Skip to content

Scheduled Jobs

Queuebase supports scheduled jobs that run automatically on a cron schedule. Scheduled jobs are defined inline on your job definition and synced to the dev server on startup.

Add a schedule property to any job with an empty input schema:

import { createJobRouter, job } from "@queuebase/nextjs";
import { z } from "zod";
export const jobs = createJobRouter({
dailyReport: job({
input: z.object({}),
handler: async ({ jobId }) => {
// runs every day at 9am UTC
return { generated: true };
},
schedule: "every day at 9am",
}),
});

The schedule property accepts three formats:

Human-readable expressions that are converted to cron under the hood.

schedule: "every 5 minutes"
schedule: "every hour"
schedule: "every 2 hours"
schedule: "every day at 9am"
schedule: "every weekday at 9am"
schedule: "every monday at 2pm"

Standard 5-field cron expressions.

schedule: "*/5 * * * *" // every 5 minutes
schedule: "0 9 * * *" // daily at 9am
schedule: "0 9 * * 1-5" // weekdays at 9am

For full control over timezone and overlap behavior.

schedule: {
cron: "0 9 * * *",
timezone: "America/New_York",
enabled: true,
overlap: "skip",
}
FieldTypeDescriptionDefault
cronstringCron expression or plain English string(required)
timezonestringIANA timezoneUTC
enabledbooleanWhether the schedule is activetrue
overlap'skip' | 'allow'What to do if the previous run is still executing'skip'
  1. Define a schedule on your job (as shown above)
  2. Run npx queuebase generate to build a manifest of your jobs and schedules
  3. Run npx queuebase dev — the dev server reads the manifest and syncs schedules into the local database
  4. The worker polls for scheduled jobs and calls back to your app to execute them

The manifest is written to .queuebase/queuebase.manifest.json. You should add the .queuebase/ directory to your .gitignore.

A router can contain both scheduled and on-demand jobs:

export const jobs = createJobRouter({
// On-demand: enqueued by your app code
sendEmail: job({
input: z.object({ to: z.string().email(), subject: z.string() }),
handler: async ({ input }) => {
// send email...
return { sent: true };
},
}),
// Scheduled: runs automatically
cleanupExpired: job({
input: z.object({}),
handler: async () => {
// cleanup logic...
return { cleaned: true };
},
schedule: "every hour",
}),
});