Back to Blog
Lesson 24 of the Redis: Redis Essentials & Data Types course
DatabasesAugust 11, 20263 min read

Building a Real-Time Notification System with Redis Pub/Sub

Learn to build a robust real-time notification system using Redis Pub/Sub. We’ll cover publisher setup, subscriber registration, and event processing.

RedisPub/SubNode.jsReal-timeMessagingBackend
A warning system with loudspeakers on a pole against a cloudy sky, signaling emergency alerts.

Previously in this course, we explored the fundamentals of Introduction to Pub/Sub: Real-Time Messaging with Redis, which provided the conceptual framework for fire-and-forget message broadcasting. In this lesson, we will move from theory to implementation by building a functional, real-time notification system within our ongoing backend project.

Understanding the Pub/Sub Lifecycle

At its core, a notification system requires a clear separation between the service that detects an event (the Publisher) and the service that reacts to it (the Subscriber). Redis acts as the high-speed message broker in this architecture, ensuring that as soon as a message is published to a channel, every active listener receives it instantly.

Unlike standard data storage where you query for information, Pub/Sub is push-based. The subscriber must be actively listening before the message is sent; otherwise, that specific notification is lost. For production systems requiring durability, we would typically look toward Redis Pub/Sub vs Streams: Building Reliable Notifications, but for real-time alerting, Pub/Sub remains the gold standard for performance.

Implementing the Publisher and Subscriber

To implement this in our Node.js project, we need two separate client instances: one to publish messages and another dedicated to listening. Because a Redis connection used for subscribing cannot issue other commands, you must maintain a dedicated client for your subscription logic.

The Subscriber Module

First, let's create a subscriber that listens for "user-alerts."

JAVASCRIPT
const Redis = require(CE9178">'ioredis');
const sub = new Redis();

sub.subscribe(CE9178">'user-alerts', (err, count) => {
  if (err) console.error(CE9178">'Subscription error:', err);
  console.log(CE9178">`Subscribed to ${count} channel(s).`);
});

sub.on(CE9178">'message', (channel, message) => {
  const data = JSON.parse(message);
  console.log(CE9178">`Received notification on ${channel}:`, data.text);
});

The Publisher Module

Now, we trigger an event from a different part of our application, perhaps when a user completes a task or receives a message.

JAVASCRIPT
const Redis = require(CE9178">'ioredis');
const pub = new Redis();

function sendNotification(userId, message) {
  const payload = JSON.stringify({ userId, text: message, timestamp: Date.now() });
  pub.publish(CE9178">'user-alerts', payload);
}

// Example usage
sendNotification(CE9178">'user_123', CE9178">'Your report is ready for download!');

Hands-on Exercise: Building a Multi-Service Alert

  1. Setup: Create two separate files: subscriber.js and publisher.js.
  2. Execute: Run node subscriber.js in one terminal window.
  3. Trigger: Run node publisher.js in another terminal.
  4. Observe: Verify that the subscriber logs the message emitted by the publisher.
  5. Challenge: Modify the publisher to send a notification to a specific "room" (e.g., room_lobby) and update your subscriber to listen to that specific channel instead of the global user-alerts.

Common Pitfalls

  • Connection Blocking: Remember that once a client issues a SUBSCRIBE command, it cannot perform other operations (like GET or SET). Always maintain a separate Redis client instance for your subscriptions.
  • The "Fire-and-Forget" Trap: If your application logic relies on history (e.g., "show me the last 5 notifications"), Pub/Sub will not provide this. For stateful messaging, you'll need to combine this with a List or Stream as discussed in our lesson on Implementing Redis Pub/Sub for Real-Time State Synchronization.
  • JSON Serialization: Redis Pub/Sub sends data as strings. Always JSON.stringify your object before publishing and JSON.parse it upon receipt to ensure your application can handle structured data.

Frequently Asked Questions

Does Pub/Sub guarantee delivery? No. If a subscriber is offline when a message is published, that subscriber will miss the message entirely.

Can I have multiple subscribers on one channel? Yes. Redis will broadcast the message to every client connected to that channel simultaneously.

Is there a limit to how many channels I can subscribe to? Redis supports an unlimited number of channels, but memory usage increases slightly with the number of active subscriptions.

Recap

We’ve successfully implemented a decoupling pattern using Redis. By separating the publisher from the subscriber, we’ve created a system that can handle real-time events without adding latency to our main application request-response cycle. This pattern is the foundation for building responsive dashboards, chat features, and real-time alerts.

Up next: We will dive into the durability side of Redis by exploring how to configure RDB snapshots and AOF logging to ensure your data survives server restarts.

Similar Posts