Common patterns for using the Checkstack Queue system. See Queue System for full documentation.
Use native recurring jobs for scheduled tasks that run at intervals.
// Schedule a recurring health check
async function scheduleHealthCheck(
queueManager: QueueManager,
configId: string,
systemId: string,
intervalSeconds: number
) {
const queue = queueManager.getQueue<HealthCheckData>('health-checks');
// Deterministic job ID for deduplication
const jobId = `healthcheck:${configId}:${systemId}`;
// Queue handles rescheduling automatically
await queue.scheduleRecurring(
jobId,
{ configId, systemId },
intervalSeconds,
{ startDelay: 0 } // Run immediately first time
);
}
// Consumer (work-queue mode - one instance per check)
const queue = queueManager.getQueue<HealthCheckData>('health-checks');
await queue.consume(async (job) => {
const { configId, systemId } = job.data;
const result = await runHealthCheck(configId, systemId);
await saveHealthCheckResult(systemId, result);
// No manual reschedule needed!
}, {
consumerGroup: 'health-checks', // Shared = work queue
maxRetries: 0, // Next interval handles failures
});
Key points:
scheduleRecurring() for automatic reschedulingUse broadcast pattern when all instances must process each message.
// Unique consumer group per instance = broadcast
const queue = queueManager.getQueue<AccessRuleSyncData>('access-rule-sync');
await queue.consume(async (job) => {
const { userId, roles } = job.data;
await accessCache.refresh(userId, roles);
}, {
consumerGroup: `access-rule-sync:${instanceId}`, // Unique!
maxRetries: 3,
});
// Trigger sync (all instances receive)
await queue.enqueue({ userId: '123', roles: ['admin'] });
Key points:
consumerGroup per instance enables broadcastUse priority for user-triggered tasks that should jump the queue.
const queue = queueManager.getQueue<ExportJob>('exports');
await queue.consume(async (job) => {
const { userId, systemIds, format } = job.data;
const filePath = await generateExport(systemIds, format);
await sendExportReady(userId, filePath);
}, {
consumerGroup: 'exports',
maxRetries: 3,
});
// User-triggered = high priority
await queue.enqueue(
{ userId, systemIds, format: 'csv' },
{ priority: 100 }
);
// Background task = low priority
await queue.enqueue(
{ userId: 'system', systemIds: allIds, format: 'csv' },
{ priority: 1 }
);
Key points:
Schedule jobs to run after a delay.
// Send reminder email in 24 hours
await queue.enqueue(
{ userId, type: 'reminder' },
{ startDelay: 86400 } // seconds
);
// Rate-limited retries
await queue.enqueue(data, {
startDelay: 60, // Wait 1 minute
priority: 5
});
Prevent duplicate jobs using custom job IDs.
// Only one sync per user at a time
await queue.enqueue(
{ userId: '123', data: newData },
{ jobId: `sync:user:123` }
);
// Second call returns existing job ID (no duplicate)
await queue.enqueue(
{ userId: '123', data: newerData },
{ jobId: `sync:user:123` }
);