Using Redis with NestJS: Caching and Pub/Sub

@rnab
3 min readJan 8, 2025

--

NestJS, the progressive Node.js framework, has quickly become a favorite for building efficient, reliable, and scalable server-side applications. One of its strengths is its robustness and extensibility, allowing developers to integrate with various technologies seamlessly. In this article, we’ll explore how to use Redis with NestJS to leverage caching and Pub/Sub functionalities, enhancing the performance and scalability of your applications.

Why Redis?

Redis is an in-memory data structure store widely used as a database, cache, and message broker. Its lightning-fast read and write operations make it an excellent choice for caching and real-time communication.

Some use cases:

  • Caching: Reduce database load by storing frequently accessed data.
  • Pub/Sub: Enable real-time communication between different parts of your application.

Setting Up Redis

First, ensure you have Redis installed on your machine. If not, follow the instructions from the Redis documentation to get it up and running.

Integrate Redis with Your NestJS Application

To use Redis with NestJS, you’ll need to install the following packages:

npm install --save @nestjs/microservices ioredis @nestjs/bull
npm install --save-dev @types/ioredis

We’re using ioredis as the Redis client, and @nestjs/microservices for extending the NestJS architecture to include microservices-like patterns.

Creating a RedisModule

Start by creating a RedisModule to encapsulate all Redis-related functionality.

// redis/redis.module.ts
import { Module } from '@nestjs/common';
import { RedisService } from './redis.service';

@Module({
providers: [RedisService],
exports: [RedisService],
})
export class RedisModule {}

Redis Service for Handling Connections

Next, create a RedisService which will handle Redis connections and operations for caching and Pub/Sub.

// redis/redis.service.ts
import { Injectable } from '@nestjs/common';
import * as Redis from 'ioredis';

@Injectable()
export class RedisService {
private readonly redisClient: Redis.Redis;
private readonly publisher: Redis.Redis;
private readonly subscriber: Redis.Redis;

constructor() {
this.redisClient = new Redis();
this.publisher = new Redis();
this.subscriber = new Redis();
}

// Caching example: setting a value
async set(key: string, value: string, ttl: number) {
await this.redisClient.set(key, value, 'EX', ttl);
}

// Caching example: getting a value
async get(key: string): Promise<string | null> {
return this.redisClient.get(key);
}

// Pub/Sub example: publishing a message
async publish(channel: string, message: string) {
await this.publisher.publish(channel, message);
}

// Pub/Sub example: subscribing to a channel
subscribe(channel: string, handler: (message: string) => void) {
this.subscriber.subscribe(channel);
this.subscriber.on('message', (chan, message) => {
if (chan === channel) {
handler(message);
}
});
}
}

Using RedisService in a Controller

Let’s create a simple controller demonstrating caching and pub/sub functionality.

// app.controller.ts
import { Controller, Get, Query } from '@nestjs/common';
import { RedisService } from './redis/redis.service';

@Controller()
export class AppController {
constructor(private readonly redisService: RedisService) {}

@Get('cache-set')
async cacheSet(@Query('key') key: string, @Query('value') value: string) {
await this.redisService.set(key, value, 3600); // Cache for 1 hour
return 'Value cached';
}

@Get('cache-get')
async cacheGet(@Query('key') key: string) {
const value = await this.redisService.get(key);
return value ? `Value: ${value}` : 'Cache miss';
}

@Get('publish')
async publish(@Query('channel') channel: string, @Query('message') message: string) {
await this.redisService.publish(channel, message);
return `Message published to ${channel}`;
}

@Get('subscribe')
async subscribe(@Query('channel') channel: string) {
this.redisService.subscribe(channel, (message) => {
console.log(`Received message from ${channel}: ${message}`);
});
return `Subscribed to ${channel} (Check your server logs for received messages)`;
}
}

Register RedisModule in AppModule

Finally, register the RedisModule in your AppModule to make RedisService accessible throughout your application.

// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { RedisModule } from './redis/redis.module';

@Module({
imports: [RedisModule],
controllers: [AppController],
})
export class AppModule {}

Running the Application

To start the application, run:

npm run start

With Redis running, you can now use the provided endpoints to cache data and leverage Pub/Sub for real-time communication.

Example Requests

Conclusion

In this article, we’ve explored integrating Redis with NestJS for caching and Pub/Sub functionalities. By leveraging Redis’s powerful capabilities, you can significantly enhance the performance and scalability of your NestJS applications.

Explore further by adding more complex data structures, transactions, and error handling to fit your specific requirements. Happy coding! 🚀

--

--

@rnab
@rnab

Written by @rnab

Typescript, Devops, Kubernetes, AWS, AI/ML, Algo Trading

No responses yet