# NestJS Enterprise Email Microservice with BullMQ & Redis Streams

_By Tayyab Mughal, Founder & AI Chief · 4 August 2026 · 2 min read_

> Architecting an enterprise-grade transactional email microservice in NestJS using BullMQ job queues, Redis streams, and exponential backoff retry policies.

Learn how to design an asynchronous email processor in NestJS with BullMQ that processes 50,000+ jobs/minute with guaranteed delivery and rate limiting.

## Why enterprise NestJS apps decouple email from request lifecycles

Synchronous email sending inside user registration HTTP controllers leads to sluggish 800ms response times and lost messages if external APIs hiccup.

By pushing email jobs to a BullMQ Redis queue, HTTP controllers return in < 5ms while background worker processors handle dispatch, rate limits, and retries asynchronously.

## NestJS Worker Processor (email.processor.ts)

Using NestJS BullMQ decorators, define the job processor with exponential backoff.

```typescript
import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bullmq';
import { Injectable, Logger } from '@nestjs/common';

@Injectable()
@Processor('email-queue')
export class EmailProcessor extends WorkerHost {
  private readonly logger = new Logger(EmailProcessor.name);

  async process(job: Job<{ to: string; subject: string; text: string }>): Promise<any> {
    this.logger.log(`Processing email job ${job.id} to ${job.data.to}`);

    const res = await fetch('https://api.sadasend.com/v1/emails', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.SADASEND_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(job.data),
    });

    if (!res.ok) {
      const err = await res.text();
      this.logger.error(`Job ${job.id} failed: ${err}`);
      throw new Error(`Dispatch failed: ${err}`);
    }

    return await res.json();
  }
}
```

## BullMQ Queue Configuration with Dead Letter Queues (DLQ)

- Configure attempts: 5 with backoff: { type: "exponential", delay: 1000 }.
- Route permanently failing jobs to a dead letter queue for engineering triage.
- Enforce rate limiting: { max: 100, duration: 1000 } to stay within tier quotas.

---

_Tags: NestJS, BullMQ, Redis, Enterprise_
