How to Setup Redis With Nest.js - Step by Step Guide

JAMAL MOHAFILJAMAL MOHAFIL
4 min read

Hi there!

Hope you're doing great with your projects

You’ve probably already heard of Redis a powerful key-value database that’s widely used for caching data. What makes Redis stand out is its incredible speed a single request can take as little as 20ms! That’s why many big companies use Redis to supercharge their systems.

In today’s blog, I’ll walk you through how to install and configure Redis in a NestJS project using the latest Redis features.

Let’s get started! 🚀


Step 1: Set Up Your NestJS Project

First, create a new NestJS project:

npm i -g @nestjs/cli
nest new redis-project

Then install the configuration package:

npm install @nestjs/config

Now, create a folder named redis and inside it create a file called redis.service.ts.


Step 2: Install Redis Dependencies

Install the Redis client library:

npm install ioredis
# or using yarn
yarn add ioredis

Step 3: Configure Redis in Your Project

1. Create .env File

Add your Redis configuration variables:

REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_USERNAME=
REDIS_PASSWORD=
REDIS_URL=

Note: If you're running Redis locally, you usually don't need the username, password, or URL.


2. Create Redis Config File

Inside the redis/config folder, create a file named redis.config.ts:

import { registerAs } from '@nestjs/config';

export default registerAs('redis', () => ({
  host: process.env.REDIS_HOST as string,
  port: parseInt(process.env.REDIS_PORT as string, 10),
  username: process.env.REDIS_USERNAME,
  password: process.env.REDIS_PASSWORD,
  url: process.env.REDIS_URL,
}));

Then register the config in your app.module.ts:

tsCopyEditimport { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import redisConfig from './redis/config/redis.config';
import { RedisService } from './redis/redis.service';

@Module({
  imports: [
    ConfigModule.forRoot(),
    ConfigModule.forFeature(redisConfig),
  ],
  providers: [],
  exports: [],
})
export class AppModule {}

Step 4: Implement Redis Logic in the Service

Inside redis.service.ts, write the following:

import {
  Inject,
  Injectable,
  OnModuleDestroy,
  OnModuleInit,
  Logger,
} from '@nestjs/common';
import { ConfigType } from '@nestjs/config';
import redisConfig from './config/redis.config';
import * as Redis from 'ioredis';

@Injectable()
export class RedisService implements OnModuleInit, OnModuleDestroy {
  private readonly logger = new Logger(RedisService.name);

  // This will be our Redis client instance, accessible throughout the service
  public redisClient: Redis.Redis;

  constructor(
    @Inject(redisConfig.KEY)
    // We're injecting the Redis config from our config file
    private readonly redisConfiguration: ConfigType<typeof redisConfig>,
  ) {}

  onModuleInit() {
    // This is where we build the configuration object for Redis
    const config = {
      host: this.redisConfiguration.host,
      port: this.redisConfiguration.port,
      username: this.redisConfiguration.username,
      password: this.redisConfiguration.password,
      url: this.redisConfiguration.url,
      retryDelayOnFailover: 100, // Retry delay when failover happens
      enableReadyCheck: true,    // Ensures Redis is ready before proceeding
      maxRetriesPerRequest: 3,   // Limits retry attempts to avoid hanging
    };

    this.logger.log('Connecting to Redis...', config);

    // Initialize the Redis client
    this.redisClient = new Redis.Redis(config);

    // Log when connected
    this.redisClient.on('connect', () => {
      this.logger.log('Redis client connected successfully');
    });

    // Log errors during connection or operation
    this.redisClient.on('error', (error) => {
      this.logger.error('Redis client error:', error);
    });
  }

  onModuleDestroy() {
    // Properly close the Redis connection when the app shuts down
    this.redisClient.quit();
    this.logger.log('Redis connection closed');
  }

  /**
   * Set a value in Redis under the given key.
   * If the value is an object, we convert it to a JSON string before saving,
   * because Redis only stores strings.
   */
  async set(key: string, value: any): Promise<string> {
    try {
      const stringValue =
        typeof value === 'object' ? JSON.stringify(value) : String(value);

      return await this.redisClient.set(key, stringValue);
    } catch (error) {
      this.logger.error(`Error setting key "${key}":`, error);
      throw error;
    }
  }

  /**
   * Get a value from Redis using a key.
   * If the value is in JSON format, we parse it to convert it back to an object.
   */
  async get<T = any>(key: string): Promise<T | null> {
    try {
      const value = await this.redisClient.get(key);
      if (!value) return null;

      try {
        // Try to parse JSON string back to object
        return JSON.parse(value);
      } catch {
        // If parsing fails, just return the raw string value
        return value as T;
      }
    } catch (error) {
      this.logger.error(`Error getting key "${key}":`, error);
      return null;
    }
  }
}

Then put redis.service.ts in your app.module.ts:

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import redisConfig from './redis/config/redis.config';
import { RedisService } from './redis/redis.service';

@Module({
  imports: [
    ConfigModule.forRoot(),
    ConfigModule.forFeature(redisConfig),
  ],
  providers: [RedisService],
  exports: [RedisService],
})
export class AppModule {}

Step 5: Use Redis in Your Repositories or Services (Example)

Example usage inside a repository:

@Injectable()
export class SessionRepository {
  constructor(private readonly redisService: RedisService) {}

  async create(session: SessionEntity): Promise<SessionEntity> {
    const raw = SessionMapper.toPrimitives(session);
    await this.redisService.set(`session:${session.id}`, raw);
    return session;
  }
}

Final Words

Congrats You’ve successfully integrated Redis into your NestJS project. You can now use it to cache data, store sessions, or optimize performance however you want

If you found this guide helpful, feel free to share it.
And if you need help with your own projects, feel free to reach out I’d be happy to help.

Have a productive day ❤️.

0
Subscribe to my newsletter

Read articles from JAMAL MOHAFIL directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

JAMAL MOHAFIL
JAMAL MOHAFIL

Hello I'm Jamal, a 16 years old content-creator and web developer with four years of experience. I've worked on a variety of projects using Next.js, Express.js, and other modern web technologies. I love building fast, scalable, and reliable applications that are easy to maintain and grow. I'm always looking for new challenges and opportunities to learn and improve. My goal is to create efficient, flexible solutions that truly meet the needs of every project.