Events
Each pg-boss instance is an EventEmitter, and contains the following events.
error
The error event could be raised during internal processing, such as scheduling and maintenance. Adding a listener to the error event is strongly encouraged because of the default behavior of Node.
If an EventEmitter does not have at least one listener registered for the 'error' event, and an 'error' event is emitted, the error is thrown, a stack trace is printed, and the Node.js process exits.
Source: Node.js Events > Error Events
Ideally, code similar to the following example would be used after creating your instance, but before start() is called.
boss.on('error', error => logger.error(error));warning
During monitoring and maintenance, pg-boss may raise warning events. The payload contains message and data properties with details about the warning.
boss.on('warning', ({ message, data }) => {
console.log('pg-boss warning:', message, data);
});Warning Types
| Type | Description | Data Properties |
|---|---|---|
slow_query | A maintenance query exceeded the slow query threshold | elapsed (seconds) |
queue_backlog | A queue has exceeded its warning threshold | name, queuedCount, warningQueued |
clock_skew | Database clock is out of sync with application server | seconds, direction |
listen_notify_unavailable | useListenNotify is enabled but a LISTEN/NOTIFY listener could not be established (for example a db adapter without listen, or PgBouncer transaction pooling); pg-boss continues with polling only | type, error |
Warning Persistence
Warnings are emitted as events by default. To also persist warnings to the database for historical tracking, enable the persistWarnings option:
const boss = new PgBoss({
connectionString: 'postgres://...',
persistWarnings: true
});When enabled, warnings are stored in the warning table and can be queried directly or viewed in the pg-boss dashboard. See SQL for the table schema.
To automatically prune old warnings, set the warningRetentionDays option:
const boss = new PgBoss({
connectionString: 'postgres://...',
persistWarnings: true,
warningRetentionDays: 30 // Auto-delete warnings older than 30 days
});wip
Emitted at most once every 2 seconds whenever at least one worker has an active job. The payload is an array that represents each worker in this instance of pg-boss.
[
{
id: 'fc738fb0-1de5-4947-b138-40d6a790749e',
workId: 'a1b2c3d4-5678-90ab-cdef-1234567890ab',
name: 'my-queue',
options: { pollingInterval: 2000 },
state: 'active',
count: 1,
createdOn: 1620149137015,
lastFetchedOn: 1620149137015,
lastJobStartedOn: 1620149137015,
lastJobEndedOn: null,
lastJobDuration: 343,
lastError: null,
lastErrorOn: null
}
]workId is the value returned by work(). When using localConcurrency, multiple worker entries in the array will share the same workId, allowing you to correlate them back to a specific work() call.
const workId = await boss.work('my-queue', { localConcurrency: 5 }, handler)
boss.on('wip', workers => {
const myWorkers = workers.filter(w => w.workId === workId)
const working = myWorkers.filter(w => w.count > 0).length
const idle = myWorkers.length - working
console.log(`working: ${working}/${myWorkers.length}, idle: ${idle}`)
})stopped
Emitted after stop() once all workers have completed their work and maintenance has been shut down.
bam
Emitted when a boss async migration (BAM) command changes status. BAM commands are database operations that run asynchronously after schema migrations, such as creating indexes on partitioned tables.
boss.on('bam', event => {
console.log(`BAM ${event.name}: ${event.status}`)
})The event payload contains:
{
id: '550e8400-e29b-41d4-a716-446655440000',
name: 'create-index',
status: 'completed', // 'in_progress', 'completed', or 'failed'
queue: 'my-queue', // queue name if applicable
table: 'j1a2b3c4...', // target table name
error: undefined // error message if status is 'failed'
}This event is useful for monitoring migration progress in production environments or for logging purposes.
flow
Emitted by the background flow resolver each time it unblocks one or more dependent jobs (created via flow()) whose parents have completed. See flowIntervalSeconds in the constructor options for how often the resolver runs.
boss.on('flow', event => {
console.log(`Resolved ${event.resolved} flow job(s) in ${event.table}`)
})The event payload contains:
{
table: 'job_common', // partition table the dependents were unblocked in
resolved: 3 // number of dependent jobs unblocked in this batch
}