Overview
RepeatableOptions (also exported as RepeatOptions) defines configuration for jobs that repeat at specified intervals.
For new implementations, use queue.upsertJobScheduler() instead of the deprecated repeat option on jobs.
Interface
interface RepeatableOptions {
name: string;
startDate?: number;
endDate?: number;
tz?: string;
limit?: number;
pattern?: string;
every?: number;
offset?: number;
}
Properties
pattern
Cron pattern for scheduling (e.g., ‘0 * * * *’ for every hour)
every
Interval in milliseconds between job executions
Use either pattern or every, not both.
limit
Maximum number of iterations to execute
startDate
Timestamp when the repeat should start
endDate
Timestamp when the repeat should end
Timezone for cron patterns (e.g., ‘America/New_York’)
offset
Offset in milliseconds to apply to the calculated next run time
If true, runs the job immediately then schedules repeats
Examples
Cron Pattern
import { Queue } from 'bullmq';
const queue = new Queue('myQueue', {
connection: { host: 'localhost', port: 6379 },
});
// Every day at midnight
await queue.upsertJobScheduler(
'daily-job',
{ pattern: '0 0 * * *' },
{
name: 'cleanup',
data: { scope: 'full' },
}
);
// Every hour
await queue.upsertJobScheduler(
'hourly-job',
{ pattern: '0 * * * *' },
{
name: 'sync',
data: {},
}
);
// Every Monday at 9 AM
await queue.upsertJobScheduler(
'weekly-report',
{ pattern: '0 9 * * 1' },
{
name: 'report',
data: { type: 'weekly' },
}
);
Fixed Interval
// Every 5 minutes
await queue.upsertJobScheduler(
'health-check',
{ every: 5 * 60 * 1000 },
{
name: 'check',
data: { service: 'api' },
}
);
// Every 30 seconds
await queue.upsertJobScheduler(
'metrics',
{ every: 30000 },
{
name: 'collect-metrics',
data: {},
}
);
With Timezone
await queue.upsertJobScheduler(
'daily-est',
{
pattern: '0 9 * * *', // 9 AM
tz: 'America/New_York',
},
{
name: 'morning-report',
data: {},
}
);
Limited Iterations
// Run 10 times only
await queue.upsertJobScheduler(
'limited-task',
{
pattern: '0 * * * *', // Every hour
limit: 10,
},
{
name: 'task',
data: {},
}
);
With Start and End Dates
await queue.upsertJobScheduler(
'campaign',
{
pattern: '0 9 * * *',
startDate: new Date('2024-01-01'),
endDate: new Date('2024-12-31'),
tz: 'America/New_York',
},
{
name: 'daily-campaign',
data: { campaignId: '123' },
}
);
await queue.upsertJobScheduler(
'immediate-repeat',
{
pattern: '0 */6 * * *', // Every 6 hours
immediately: true, // Run now, then every 6 hours
},
{
name: 'sync',
data: {},
}
);
With Offset
// Run 5 seconds after the scheduled time
await queue.upsertJobScheduler(
'delayed-start',
{
every: 60000, // Every minute
offset: 5000, // But 5 seconds after
},
{
name: 'task',
data: {},
}
);
Cron patterns use the following format:
* * * * *
┬ ┬ ┬ ┬ ┬
│ │ │ │ │
│ │ │ │ └─── day of week (0 - 7) (Sunday is 0 or 7)
│ │ │ └────────── month (1 - 12)
│ │ └─────────────────── day of month (1 - 31)
│ └──────────────────────────── hour (0 - 23)
└───────────────────────────────────── minute (0 - 59)
Common Patterns
// Every minute
'* * * * *'
// Every 5 minutes
'*/5 * * * *'
// Every hour at minute 30
'30 * * * *'
// Every day at midnight
'0 0 * * *'
// Every day at 2:30 PM
'30 14 * * *'
// Every Monday at 9 AM
'0 9 * * 1'
// Every 1st of the month at midnight
'0 0 1 * *'
// Every weekday at 6 PM
'0 18 * * 1-5'
// Every 15 minutes during business hours
'*/15 9-17 * * 1-5'
Timezone Support
Timezones use IANA timezone identifiers:
// Common timezones
'America/New_York'
'America/Los_Angeles'
'America/Chicago'
'Europe/London'
'Europe/Paris'
'Asia/Tokyo'
'Asia/Shanghai'
'Australia/Sydney'
'UTC'
Migration from Deprecated API
Old (Deprecated)
await queue.add(
'task',
{ data: 'value' },
{
repeat: {
pattern: '0 * * * *',
tz: 'America/New_York',
},
}
);
New (Recommended)
await queue.upsertJobScheduler(
'task-scheduler',
{
pattern: '0 * * * *',
tz: 'America/New_York',
},
{
name: 'task',
data: { data: 'value' },
}
);