DEV Community

Cover image for Boosting Performance with Two-Tier Caching in NestJS
Suren Krmoian
Suren Krmoian

Posted on

Boosting Performance with Two-Tier Caching in NestJS

Boosting Performance with Two-Tier Caching in NestJS

Let's cut right to the chase. If you're building web applications with NestJS, you know performance and scalability are non-negotiable. One way to keep things zippy is by using a two-tier caching strategy. That's where NestJS RedisX comes into play. It's an open-source toolkit that simplifies Redis integration in NestJS apps, making it ridiculously easy to set up a two-layer cache. Let's get our hands dirty with some code and see how you can implement this.

What's Two-Tier Caching Anyway?

Alright, so you've got two levels of caching here. The first level (L1) is your in-memory cache. It's right there on the server with your application, super fast, low latency. But, of course, it's limited by your server's memory.

Then there's the second level (L2), which is a Redis-based cache. This one lives across the network, can store a ton more data, and is shared across multiple instances. So, if L1 doesn't have what you're looking for, L2 steps in before you have to hit the database. Pretty neat, right?

Setting It Up with NestJS RedisX

Now, let's dive into the implementation. With RedisX, setting up this cache is a breeze. Follow these steps to get it rolling.

Step 1: Get the Packages

First things first, you need to install the necessary RedisX packages. Pop open your terminal and run:

npm install @nestjs-redisx/core @nestjs-redisx/cache
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure the Redis Module

Next, you'll want to configure the RedisModule in your AppModule. This is where the magic starts:

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { RedisModule } from '@nestjs-redisx/core';
import { CachePlugin } from '@nestjs-redisx/cache';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    RedisModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      plugins: [
        CachePlugin.registerAsync({
          imports: [ConfigModule],
          inject: [ConfigService],
          useFactory: (config: ConfigService) => ({
            l1: { enabled: true, maxSize: 1000, ttl: 60 },
            defaultTtl: config.get('CACHE_TTL', 300),
          }),
        }),
      ],
      useFactory: (config: ConfigService) => ({
        clients: {
          type: 'single',
          host: config.get('REDIS_HOST', 'localhost'),
          port: config.get('REDIS_PORT', 6379),
        },
      }),
    }),
  ],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Step 3: Use Caching in Your Services

Now, let's put that cache to work. Use the @Cached decorator in your services. It'll check the L1 cache first, then L2, and update both as needed:

import { Injectable } from '@nestjs/common';
import { Cached } from '@nestjs-redisx/cache';

@Injectable()
export class ProductService {
  @Cached({ key: 'product:{0}', ttl: 3600 })
  async getProduct(id: string) {
    return this.db.findProduct(id);
  }
}
Enter fullscreen mode Exit fullscreen mode

Why Bother with Two-Tier Caching?

  • Speed: L1 cache is lightning fast, reducing latency to virtually nothing.
  • Scalability: L2 lets you handle big datasets and share that cached goodness across instances.
  • Efficiency: RedisX’s plugin-based setup is smooth and reduces the load on your database, keeping your app peppy.

Wrapping It Up

There you have it. A two-tier caching system using NestJS RedisX. It's a solid strategy to keep your app running smoothly even under heavy loads. For a deeper dive and more configuration options, check out the NestJS RedisX documentation.

Top comments (0)