NextMQ

Schedulers & repeatables

Job Schedulers are the forward-looking way to run recurring work. NextMQ owns the scheduling clock, so repeating jobs fire even while your functions are cold.

Upserting a scheduler#

upsertJobScheduler creates or updates a scheduler by key. Use a cron pattern or a fixed every interval. Upsert is idempotent, so it is safe to run from startup code.

import { Queue } from '@nextmq/sdk'

const reportQueue = new Queue('reports')

// Cron: every day at 09:00 in a fixed timezone.
await reportQueue.upsertJobScheduler('daily-report', {
  pattern: '0 9 * * *',
  tz: 'Europe/Berlin',
}, {
  name: 'report',
  data: { kind: 'daily' },
})

// Fixed interval: every 15 minutes.
await reportQueue.upsertJobScheduler('healthcheck', {
  every: 15 * 60 * 1000,
})

Repeat options#

Common cron patterns:

PatternRuns
0 * * * *At the top of every hour.
0 9 * * *Every day at 09:00 in the scheduler timezone.
0 9 * * 1Every Monday at 09:00.
OptionDescription
patternCron expression for the schedule.
everyFixed interval in milliseconds (alternative to pattern).
limitMaximum number of times to repeat.
tzTimezone for cron evaluation.
startDateDon't fire before this time.
endDateDon't fire after this time.
immediatelyProduce the first job right away rather than waiting a full interval.
Note
Set tz for calendar schedules that must follow a specific timezone. Cron schedules with tz follow that timezone's civil calendar, including DST. Fixed every schedules are duration-based.
Note
Scheduler templates produce ordinary jobs with the given name, data, and safe job options. Template options cannot include jobId, repeat, delay, deduplication, or callbackUrl; scheduled jobs use the queue's canonical worker registration URL.

What the worker receives#

A scheduler creates ordinary jobs. The worker sees the template name anddata, exactly as if you had called queue.add().

await reportQueue.upsertJobScheduler(
  'daily-report',
  { pattern: '0 9 * * *', tz: 'Europe/Berlin' },
  { name: 'build-report', data: { range: 'yesterday' } },
)

new Worker('reports', async (job) => {
  // job.name === 'build-report'
  // job.data.range === 'yesterday'
})

Reading and removing schedulers#

// All schedulers on the queue
const all = await reportQueue.getJobSchedulers()

// A single scheduler by key
const one = await reportQueue.getJobScheduler('daily-report')

// Remove a scheduler
await reportQueue.removeJobScheduler('daily-report')
Note
NextMQ supports the modern Job Scheduler CRUD. Legacy repeatable-job management (getRepeatableJobs, removeRepeatableByKey) is intentionally omitted — two ways to manage the same thing is worse than one. A limited repeat option on add() still exists for simple cases, but schedulers are preferred.

Why this works when functions sleep#

The scheduler clock lives on NextMQ, not in your app. When a scheduled job is due, NextMQ produces it and calls your worker route via webhook — the same path as any other job. Your app doesn't need to be awake for the schedule to advance.

Create important schedulers in startup registration so a fresh deployment has both worker registration and repeat jobs in place. The full scheduler method and option list is in the SDK reference.

Tip
A scheduler stops producing new jobs after its limit is reached or afterendDate. Remove or upsert the scheduler again when you intentionally want to resume it.