CodePark/ questions / Microservices, queues & events
START PRACTICINGPRACTICE
Backend question · NestJS › Microservices, queues & events

How do you run background jobs with BullMQ in Nest, for example sending a welcome email after signup?

BullModule.forRoot({ connection: { host: "localhost", port: 6379 } });
BullModule.registerQueue({ name: "email" });

constructor(@InjectQueue("email") private queue: Queue) {}
await this.queue.add("welcome", { userId }, { attempts: 3, backoff: { type: "exponential", delay: 1000 } });

@Processor("email")
export class EmailConsumer extends WorkerHost {
  async process(job: Job<{ userId: number }>) {
    if (job.name === "welcome") await this.mail.sendWelcome(job.data.userId);
  }
}

Use @nestjs/bullmq. The API adds a job to a queue, and a separate worker class processes it. BullMQ stores the jobs in Redis.

Setup. BullModule.forRoot() sets the Redis connection. BullModule.registerQueue() registers a named queue.

The producer adds jobs. It injects the queue with @InjectQueue("email") and calls queue.add(name, data, options). Useful options:

  • attempts and backoff for retries
  • delay for scheduling
  • removeOnComplete for cleanup

The HTTP request returns as soon as the job is stored. The user doesn't wait for the email.

The consumer runs jobs. It is a class decorated with @Processor("email"). It extends WorkerHost and implements process(job). You must register it as a provider. @OnWorkerEvent("completed") or @OnWorkerEvent("failed") lets you react to job events.

Workers can run in the same app or in separate processes. So slow work can scale separately from the API.

  • Set up with BullModule.forRoot and registerQueue.
  • The producer uses @InjectQueue and queue.add, with retry options.
  • The consumer is a @Processor class that extends WorkerHost.
  • Jobs are stored in Redis, so the request returns immediately.
  • Workers can scale separately from the API.