Persistent Job Scheduling
New Feature: Persistent Job Scheduling
Schedule jobs to run on a recurring basis using cron expressions or fixed intervals. Schedules are persisted in the database and survive worker restarts.
Creating Schedules
// Interval-based schedule (ID defaults to job name)
await MetricsJob.schedule({ endpoint: '/api/health' })
.every('10s')
.run()
// Cron-based schedule with custom ID
await CleanupJob.schedule({ days: 30 })
.id('daily-cleanup')
.cron('0 0 * * *')
.timezone('Europe/Paris')
.run()
// With constraints
await ReportJob.schedule({ type: 'weekly' })
.cron('0 9 * * MON')
.from(new Date('2024-01-01'))
.to(new Date('2024-12-31'))
.limit(52)
.run()Managing Schedules
import { Schedule } from '@boringnode/queue'
const schedule = await Schedule.find('MetricsJob')
await schedule.pause()
await schedule.resume()
await schedule.trigger() // Immediate run
await schedule.delete()
// List schedules
const active = await Schedule.list({ status: 'active' })Schedule Options
| Method | Description |
|---|---|
| .id(string) | Unique identifier (defaults to job name) |
| .every(duration) | Fixed interval ('5s', '1m', '1h', '1d') |
| .cron(expression) | Cron schedule |
| .timezone(tz) | Timezone for cron (default: 'UTC') |
| .from(date) / .to(date) | Date boundaries |
| .between(from, to) | Shorthand for date range |
| .limit(n) | Maximum number of runs |
How It Works
- Schedules are persisted via the adapter (Redis, Knex)
- Worker automatically polls and dispatches due schedules
- Multiple workers can run concurrently - atomic claiming prevents duplicates
- Failed jobs don't affect the schedule - next run still occurs