Skip to content

Pub/Sub Plugin

Typed Redis Pub/Sub messaging: real-time events between services and instances, WebSocket broadcasting, and cross-instance signaling — with a @Subscribe decorator and a dedicated subscriber connection managed for you.

Overview

Redis Pub/Sub delivers a published message to every currently-subscribed connection — instantly, across all application instances. The catch: a Redis connection in subscriber mode cannot execute regular commands, so naive setups break their main client. This plugin clones a dedicated subscriber connection from your named client automatically and multiplexes any number of local handlers over it.

ChallengeWithout the pluginWith the Pub/Sub Plugin
Cross-instance eventsPolling or ad-hoc socketsInstant fan-out via Redis
Subscriber-mode connectionBreaks the shared clientDedicated connection, managed lifecycle
Handler wiringManual client.on('message') routing@Subscribe auto-discovery + typed payloads

Key Features

  • Typed publish/subscribe — JSON payloads with generics; non-JSON messages interop as raw strings
  • Pattern subscriptions — Redis globs (user.*, order.?, news.[ab]) with the matching pattern delivered alongside the concrete channel
  • @Subscribe decorator — provider methods auto-subscribed on startup
  • Local multiplexing — many handlers per channel share one Redis subscription; released when the last unsubscribes
  • Channel prefixing — optional namespace that stays invisible to handlers
  • Shutdown hygiene — all subscriptions released on module destroy

Installation

bash
npm install @nestjs-redisx/core @nestjs-redisx/pubsub ioredis
bash
npm install @nestjs-redisx/core @nestjs-redisx/pubsub redis

Basic Configuration

typescript
import { Module } from '@nestjs/common';
import { RedisModule } from '@nestjs-redisx/core';
import { PubSubPlugin } from '@nestjs-redisx/pubsub';

@Module({
  imports: [
    RedisModule.forRoot({
      clients: {
        host: 'localhost',
        port: 6379,
      },
      plugins: [
        new PubSubPlugin({
          channelPrefix: 'app:', // optional namespace for all channels
        }),
      ],
    }),
  ],
})
export class AppModule {}

Publishing

typescript
import { Injectable, Inject } from '@nestjs/common';
import { PUBSUB_SERVICE, IPubSubService } from '@nestjs-redisx/pubsub';
import { UserCreatedEvent } from './types';

@Injectable()
export class UserPublisher {
  constructor(
    @Inject(PUBSUB_SERVICE)
    private readonly pubsub: IPubSubService,
  ) {}

  async userCreated(user: UserCreatedEvent): Promise<void> {
    // Payload is JSON-serialized; returns the number of subscribers reached.
    const receivers = await this.pubsub.publish('user.created', user);
    if (receivers === 0) {
      // Pub/Sub is fire-and-forget: nobody was listening right now.
    }
  }
}

Subscribing with the Decorator

typescript
import { Injectable } from '@nestjs/common';
import { Subscribe, IPubSubMessage } from '@nestjs-redisx/pubsub';
import { UserCreatedEvent, NotificationGateway } from './types';

@Injectable()
export class UserEventsHandler {
  constructor(private readonly gateway: NotificationGateway) {}

  // Auto-subscribed on startup via discovery.
  @Subscribe('user.created')
  onUserCreated(message: IPubSubMessage<UserCreatedEvent>): void {
    this.gateway.broadcast('user:new', message.data);
  }

  // Redis glob patterns: *, ?, [..]
  @Subscribe({ pattern: 'order.*' })
  onAnyOrderEvent(message: IPubSubMessage): void {
    // message.pattern === 'order.*', message.channel === concrete channel
    this.gateway.broadcast(message.channel, message.data);
  }
}

Pub/Sub is fire-and-forget

Messages are delivered only to connections subscribed at the moment of publishing — there is no persistence, replay, or acknowledgment. For guaranteed, replayable delivery use the Streams plugin.

Documentation

TopicDescription
ConfigurationOptions and the dedicated subscriber connection
@Subscribe DecoratorAuto-discovered channel and pattern handlers
Service APIProgrammatic publish/subscribe/unsubscribe
RecipesWebSocket broadcast and event patterns
TestingIn-memory driver support
TroubleshootingDelivery, drivers, and topology notes

Released under the MIT License.