Skip to main content
When a worker completes a job, you often need to return data that can be accessed by other parts of your application. BullMQ provides several ways to handle job results.

Basic Return Values

Return data from your processor function:
The return value can be any JSON-serializable object: strings, numbers, booleans, objects, arrays, or null.

Accessing Return Values

From Worker Events

Listen to the completed event on the worker:

From Queue Events

Use QueueEvents to listen across all workers:
QueueEvents provides a global view of all job events, regardless of which worker processed the job.

From the Job Instance

Retrieve the return value later:

Using getJob

Fetch the job and its result later:

Return Value Examples

Simple Values

Complex Objects

Arrays

Storing Results Reliably

Storing data in the completed event handler is less reliable because the event handler could fail while the job still completes successfully.
Not recommended:
Recommended:
If storing the result fails in the processor, the job will fail and can be retried. If storing fails in an event handler, the job is already completed and the failure goes unnoticed.

Using a Results Queue

For robust microservice architectures, use a dedicated results queue:
Benefits:
  • Reliability: Results are stored in Redis until successfully processed
  • Decoupling: Result storage can be handled by a separate service
  • Retry logic: Failed storage operations are automatically retried
  • Resilience: If the results service is down, results queue up automatically

Microservice Pattern

Chain services together using result queues:

Combining Return Values with Progress

TypeScript Type Safety

Define return value types:

Best Practices

1

Return meaningful data

Include useful information like IDs, counts, timestamps, and status indicators.
2

Keep return values JSON-serializable

Avoid functions, circular references, or non-serializable objects.
3

Store critical data in the processor

Don’t rely solely on event handlers for important data persistence.
4

Use results queues for microservices

Decouple services and improve reliability with dedicated results queues.
5

Include context in return values

Add timestamps, job IDs, and other metadata to make results self-describing.
6

Handle large results appropriately

For large data, store in external storage (S3, database) and return references.

Handling Large Results

For large data, avoid storing everything in Redis:

Workers Overview

Learn about worker basics

Queue Events

Monitor job events globally

Job API

Job instance methods and properties

Retrying Failing Jobs

Handle job failures

API Reference