Every BullMQ queue stores metadata in Redis that contains important configuration and state information. You can retrieve this metadata to monitor and understand your queue’s current settings.
Use the getMeta method to retrieve all queue metadata:
Method Signature
async getMeta(): Promise<QueueMetadata>
Example
import { Queue } from 'bullmq';
const queue = new Queue('tasks');
const meta = await queue.getMeta();
console.log(meta);
The metadata object contains the following fields:
The global concurrency limit, if set. This determines the maximum number of jobs that can be processed simultaneously across all workers.See Global Concurrency for more details.
The maximum number of jobs allowed in the rate limit window, if rate limiting is enabled.See Global Rate Limit for more details.
The duration (in milliseconds) of the rate limit window, if rate limiting is enabled.See Global Rate Limit for more details.
Whether the queue is currently paused. When paused, no new jobs will be processed.
The maximum length of the events stream. Default is 10,000 events.
The BullMQ library version that created or last updated the queue metadata, in the format bullmq:x.y.z.
Example Output
import { Queue } from 'bullmq';
const queue = new Queue('tasks');
// Configure the queue
await queue.setGlobalConcurrency(5);
await queue.setGlobalRateLimit(100, 60000);
// Get metadata
const meta = await queue.getMeta();
console.log(meta);
// Output:
// {
// concurrency: 5,
// max: 100,
// duration: 60000,
// paused: false,
// maxLenEvents: 10000,
// version: 'bullmq:5.0.0'
// }
Practical Examples
Example 1: Health Check
Create a health check endpoint that includes queue metadata:
import { Queue } from 'bullmq';
import express from 'express';
const app = express();
const queue = new Queue('tasks');
app.get('/health/queue', async (req, res) => {
const meta = await queue.getMeta();
const counts = await queue.getJobCounts();
res.json({
status: 'ok',
metadata: meta,
counts: counts,
timestamp: new Date().toISOString()
});
});
Example 2: Monitoring Dashboard
import { Queue } from 'bullmq';
const queue = new Queue('tasks');
async function getQueueStatus() {
const meta = await queue.getMeta();
const waiting = await queue.getWaitingCount();
const active = await queue.getActiveCount();
const completed = await queue.getCompletedCount();
const failed = await queue.getFailedCount();
return {
version: meta.version,
paused: meta.paused,
concurrency: meta.concurrency ?? 'unlimited',
rateLimit: meta.max && meta.duration
? `${meta.max} jobs per ${meta.duration}ms`
: 'none',
counts: {
waiting,
active,
completed,
failed,
total: waiting + active + completed + failed
}
};
}
// Use it
const status = await getQueueStatus();
console.log(status);
Example 3: Configuration Validation
Verify queue configuration matches expectations:
import { Queue } from 'bullmq';
const queue = new Queue('tasks');
async function validateQueueConfig() {
const meta = await queue.getMeta();
// Check concurrency
if (meta.concurrency !== 10) {
console.warn(`Expected concurrency: 10, got: ${meta.concurrency}`);
await queue.setGlobalConcurrency(10);
}
// Check rate limit
if (meta.max !== 100 || meta.duration !== 60000) {
console.warn('Rate limit mismatch');
await queue.setGlobalRateLimit(100, 60000);
}
// Check pause state
if (meta.paused) {
console.warn('Queue is paused!');
}
console.log('Queue configuration validated');
}
await validateQueueConfig();
Example 4: Version Checking
Ensure queue was created with a compatible BullMQ version:
import { Queue } from 'bullmq';
const queue = new Queue('tasks');
async function checkVersion() {
const meta = await queue.getMeta();
const version = await queue.getVersion();
console.log(`Queue version: ${version}`);
console.log(`Meta version: ${meta.version}`);
// Parse version
const match = version.match(/bullmq:(\d+)\.(\d+)\.(\d+)/);
if (match) {
const [, major, minor, patch] = match;
console.log(`Major: ${major}, Minor: ${minor}, Patch: ${patch}`);
if (parseInt(major) < 5) {
console.warn('Queue was created with an old version of BullMQ');
}
}
}
await checkVersion();
Example 5: Pause Status Monitor
import { Queue } from 'bullmq';
const queue = new Queue('tasks');
// Monitor pause status every 10 seconds
setInterval(async () => {
const meta = await queue.getMeta();
if (meta.paused) {
console.log('⚠️ Queue is PAUSED');
} else {
console.log('✓ Queue is ACTIVE');
}
}, 10000);
Pause State
You can check pause state via metadata or a dedicated method:
// Using metadata
const meta = await queue.getMeta();
const isPaused = meta.paused;
// Using dedicated method
const isPausedDirect = await queue.isPaused();
Global Concurrency
// Using metadata
const meta = await queue.getMeta();
const concurrency = meta.concurrency;
// Using dedicated method
const concurrencyDirect = await queue.getGlobalConcurrency();
Global Rate Limit
// Using metadata
const meta = await queue.getMeta();
const rateLimit = { max: meta.max, duration: meta.duration };
// Using dedicated method
const rateLimitDirect = await queue.getGlobalRateLimit();
Queue metadata is stored in Redis under a hash key:
// Redis key pattern: {prefix}:{queueName}:meta
// Default: bull:{queueName}:meta
// You can view it directly in Redis CLI:
// HGETALL bull:tasks:meta
The metadata is automatically updated when you:
- Call
setGlobalConcurrency()
- Call
setGlobalRateLimit()
- Call
pause() or resume()
- Create a new queue instance
Configuration Options
You can configure the events stream length when creating a queue:
import { Queue } from 'bullmq';
const queue = new Queue('tasks', {
streams: {
events: {
maxLen: 5000 // Keep last 5000 events instead of default 10000
}
}
});
const meta = await queue.getMeta();
console.log(meta.maxLenEvents); // 5000