NestJS Profiler
Tutorials

Cache profiling

Track cache GET_HIT/GET_MISS/SET/DEL operations and the hit ratio in the profiler's Cache panel with nest-profiler-cache.

This tutorial shows how to add the cache collector to profile @nestjs/cache-manager operations in a NestJS application.

Prerequisites

  • @eleven-labs/nest-profiler installed and configured
  • @nestjs/cache-manager and cache-manager installed

Step 1 - Install the package

pnpm add @eleven-labs/nest-profiler-cache@alpha @nestjs/cache-manager cache-manager

Step 2 - Register the modules

app.module.ts
import { CacheModule } from '@nestjs/cache-manager';
import { ConditionalModule } from '@nestjs/config';
import { ProfilerModule } from '@eleven-labs/nest-profiler';
import { CacheCollectorModule } from '@eleven-labs/nest-profiler-cache';

const isProfilerEnabled = (env: NodeJS.ProcessEnv) => env['PROFILER_ENABLED'] === 'true';

@Module({
  imports: [
    CacheModule.register({ isGlobal: true, ttl: 30000 }), // 30s TTL
    ConditionalModule.registerWhen(ProfilerModule.forRoot({ isGlobal: true }), isProfilerEnabled),
    ConditionalModule.registerWhen(CacheCollectorModule.forRoot(), isProfilerEnabled),
  ],
})
export class AppModule {}

Step 3 - Use the cache in a service or controller

import { CACHE_MANAGER } from '@nestjs/cache-manager';
import type { Cache } from 'cache-manager';

@Controller('posts')
export class PostsController {
  constructor(
    private readonly http: HttpService,
    @Inject(CACHE_MANAGER) private readonly cache: Cache,
  ) {}

  @Get()
  async getPosts(): Promise<unknown[]> {
    const CACHE_KEY = 'posts:list';

    const cached = await this.cache.get<unknown[]>(CACHE_KEY);
    if (cached) return cached;

    const { data } = await firstValueFrom(
      this.http.get('https://jsonplaceholder.typicode.com/posts?_limit=5'),
    );
    await this.cache.set(CACHE_KEY, data, 30000);
    return data;
  }
}

Step 4 - Test it

# First call - MISS + SET
curl http://localhost:3000/posts

# Second call - HIT
curl http://localhost:3000/posts

Open /_profiler/{token} and navigate to the Cache tab.

First call profile shows:

  • GET_MISS for posts:list
  • SET for posts:list (after fetching from API)
  • Toolbar badge: 0H/1M

Second call profile shows:

  • GET_HIT for posts:list
  • Toolbar badge: 1H/0M

Using Redis

To use Redis as the cache store, add @keyv/redis:

pnpm add @keyv/redis keyv
import Keyv from 'keyv';
import { KeyvAdapter } from '@nestjs/cache-manager';
import KeyvRedis from '@keyv/redis';

CacheModule.register({
  isGlobal: true,
  stores: [
    new KeyvAdapter(
      new Keyv({ store: new KeyvRedis('redis://localhost:6379'), namespace: 'profiler' }),
    ),
  ],
}),

The cache collector works transparently with any store since it patches the CACHE_MANAGER instance's methods at the NestJS abstraction layer.

How it works

At onModuleInit the collector wraps the CACHE_MANAGER's get, set, and del methods to record each operation (type, key, duration) into the active request profile. See How it works on the package page.

Powered & maintained by

On this page