# Improving NestJS Speed with Redis Caching Solutions

Caching is a powerful technique to speed up your [applications](https://bytescrum.com/), making them more responsive and efficient. In this post, I'll walk you through how to integrate Redis cache into a NestJS application. [Redis](https://www.tomray.dev/nestjs-caching-redis) is an in-memory data structure store that can be used as a database, cache, and message broker. By the end of this tutorial, you'll have a solid understanding of how to set up and use Redis in your NestJS projects.

## Why Use Redis?

Redis offers several benefits for caching:

* **Speed:** Since Redis is an in-memory store, it's incredibly fast.
    
* **Persistence:** It supports data persistence, allowing you to save snapshots of your data to disk.
    
* **Data Structures:** Redis supports various data structures such as strings, hashes, lists, sets, and more.
    
* **Scalability:** Redis can be scaled easily to handle large amounts of data and high request rates.
    

## Setting Up Redis

Before we dive into the code, make sure you have Redis installed and running. You can either download Redis from its official website or use a Docker container for a quick setup:

```bash
docker run --name redis -p 6379:6379 -d redis
```

## Setting Up NestJS

If you don't already have a [NestJS](https://blog.bytescrum.com/introduction-to-nestjs-a-beginners-guide) project, let's create a new one:

```bash
nest new redis-cache-example
cd redis-cache-example
```

## Installing Dependencies

Next, we'll need to install some packages for Redis and caching:

```bash
npm install cache-manager cache-manager-redis-store redis
```

## Integrating Redis with NestJS

### 1\. Configure Cache Module

First, we need to configure the CacheModule in our `app.module.ts` file to use Redis:

```typescript
import { Module, CacheModule } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import * as redisStore from 'cache-manager-redis-store';

@Module({
  imports: [
    CacheModule.register({
      store: redisStore,
      host: 'localhost', // Redis server host
      port: 6379,        // Redis server port
      ttl: 600,          // Time to live (seconds)
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Here, we configure the CacheModule to use Redis as our cache store, specifying the host and port where Redis is running. We also set a time-to-live (TTL) of 600 seconds for cached data.

### 2\. Using Cache in Services

Now, let's use the cache in our service. We'll inject the cache manager and use it to cache data. Here's an example in `app.service.ts`:

```typescript
import { Injectable, Inject } from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';

@Injectable()
export class AppService {
  constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}

  async getHello(): Promise<string> {
    const cacheKey = 'hello_cache';
    let cachedData = await this.cacheManager.get<string>(cacheKey);

    if (!cachedData) {
      cachedData = 'Hello World!';
      await this.cacheManager.set(cacheKey, cachedData, { ttl: 600 }); // Cache for 10 minutes
    }

    return cachedData;
  }
}
```

In this service, we first try to get the cached data using `cacheManager.get`. If there's no cached data, we set it using `cacheManager.set`.

### 3\. Handling Cache in Controllers

Next, we use this service method in our controller. Here’s how our `app.controller.ts` looks:

```typescript
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  async getHello(): Promise<string> {
    return this.appService.getHello();
  }
}
```

This controller simply calls the `getHello` method from our service to return the cached or newly set data.

## Advanced Caching Techniques

### Caching Method Results

NestJS provides a `@Cacheable` decorator to cache method results effortlessly. Here’s how you can use it:

```typescript
import { Injectable } from '@nestjs/common';
import { Cacheable } from 'nestjs-cacheable';

@Injectable()
export class AppService {
  @Cacheable({ ttl: 600 }) // Cache for 10 minutes
  async getHello(): Promise<string> {
    return 'Hello World!';
  }
}
```

With the `@Cacheable` decorator, the method result is automatically cached, saving you from manually handling cache logic.

### Invalidating Cache

Sometimes, you might need to invalidate the cache when the underlying data changes. Use `cacheManager.del` to remove cached data. Here’s an example:

```typescript
import { Injectable, Inject, CACHE_MANAGER } from '@nestjs/common';
import { Cache } from 'cache-manager';

@Injectable()
export class AppService {
  constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}

  async updateHello(newData: string): Promise<void> {
    const cacheKey = 'hello_cache';
    await this.cacheManager.del(cacheKey);
    // Update the data in your database or other persistent storage
  }
}
```

In this example, when `updateHello` is called, the cache for `hello_cache` is invalidated, ensuring that subsequent requests fetch the latest data.

<details data-node-type="hn-details-summary"><summary>Conclusion</summary><div data-type="detailsContent">Integrating Redis cache into your NestJS application can significantly enhance performance and scalability. In this blog post, we covered the basics of setting up Redis, configuring the CacheModule in NestJS, and implementing caching in services and controllers. By leveraging these techniques, you can make your NestJS applications more responsive and provide a better user experience.</div></details>

Happy coding!
