# NestJS dan Redis di Tahun 2026: Caching, Sessions, dan Pertanyaan Interview > Panduan lengkap integrasi NestJS dengan Redis untuk caching dan session management, dilengkapi pertanyaan interview untuk persiapan wawancara kerja Node.js. - Published: 2026-09-10 - Updated: 2026-09-10 - Author: Anthony Fillion-Maillet - Tags: nestjs, redis, caching, nodejs, interview - Reading time: 12 min --- Integrasi NestJS dengan Redis mengubah performa aplikasi secara signifikan dengan menggantikan query database dengan pencarian di memori. Kombinasi @nestjs/cache-manager untuk caching dan express-session dengan connect-redis untuk persistensi session mencakup dua kasus penggunaan Redis yang paling umum dalam aplikasi backend. > **Poin Penting** > > Caching Redis di NestJS mengurangi beban database dengan menyimpan data yang sering diakses di memori. Session management dengan Redis memungkinkan horizontal scaling dengan berbagi state session antar instance. ## Mengatur @nestjs/cache-manager dengan Redis Modul cache-manager dipindahkan ke package terpisah sejak NestJS 10. Instalasi memerlukan wrapper NestJS dan cache store yang mendasarinya. Adapter @keyv/redis adalah pendekatan yang direkomendasikan untuk integrasi Redis dengan cache-manager v5. ```bash # Install package yang diperlukan npm install @nestjs/cache-manager cache-manager @keyv/redis ``` Registrasi modul mengkonfigurasi koneksi Redis dan TTL default. Opsi `isGlobal` membuat cache tersedia di semua modul tanpa perlu import ulang. ```typescript // app.module.ts import { Module } from '@nestjs/common'; import { CacheModule } from '@nestjs/cache-manager'; import KeyvRedis from '@keyv/redis'; @Module({ imports: [ CacheModule.registerAsync({ isGlobal: true, useFactory: () => ({ stores: [ new KeyvRedis(process.env.REDIS_URL || 'redis://localhost:6379'), ], ttl: 60000, // Default TTL dalam milidetik }), }), ], }) export class AppModule {} ``` Array `stores` menerima beberapa cache store untuk multi-tier caching. Environment produksi biasanya menggunakan Redis sebagai store utama, dengan fallback in-memory opsional untuk development. ## Cache Injection dan Service-Level Caching Token `CACHE_MANAGER` memberikan akses langsung ke cache untuk operasi level service. Pendekatan ini menawarkan kontrol lebih dibanding HTTP caching otomatis ketika business logic menentukan kapan cache harus di-invalidasi. ```typescript // users.service.ts import { Injectable, Inject } from '@nestjs/common'; import { CACHE_MANAGER, Cache } from '@nestjs/cache-manager'; import { UsersRepository } from './users.repository'; import { User } from './user.entity'; @Injectable() export class UsersService { constructor( @Inject(CACHE_MANAGER) private cache: Cache, private usersRepository: UsersRepository, ) {} async findById(id: string): Promise { // Cek cache terlebih dahulu const cacheKey = `user:${id}`; const cached = await this.cache.get(cacheKey); if (cached) { return cached; } // Cache miss: ambil dari database const user = await this.usersRepository.findById(id); if (user) { await this.cache.set(cacheKey, user, 300000); // TTL 5 menit } return user; } async update(id: string, data: Partial): Promise { const user = await this.usersRepository.update(id, data); // Invalidate cache setelah update await this.cache.del(`user:${id}`); return user; } async delete(id: string): Promise { await this.usersRepository.delete(id); await this.cache.del(`user:${id}`); } } ``` Pola cache-aside yang diimplementasikan di atas memeriksa cache sebelum query database. Invalidasi terjadi saat operasi write untuk menjaga konsistensi data antara cache dan sumber kebenaran. ## HTTP Response Caching dengan Interceptor NestJS menyediakan `CacheInterceptor` untuk caching respons HTTP secara otomatis. Decorator `@CacheTTL()` dan `@CacheKey()` mengkustomisasi perilaku per endpoint. ```typescript // products.controller.ts import { Controller, Get, Param, UseInterceptors } from '@nestjs/common'; import { CacheInterceptor, CacheTTL, CacheKey } from '@nestjs/cache-manager'; import { ProductsService } from './products.service'; @Controller('products') @UseInterceptors(CacheInterceptor) export class ProductsController { constructor(private productsService: ProductsService) {} @Get() @CacheTTL(120000) // 2 menit untuk daftar produk async findAll() { return this.productsService.findAll(); } @Get(':id') @CacheTTL(300000) // 5 menit untuk produk individual async findOne(@Param('id') id: string) { return this.productsService.findById(id); } @Get('category/:category') @CacheKey('products-by-category') @CacheTTL(180000) async findByCategory(@Param('category') category: string) { return this.productsService.findByCategory(category); } } ``` Interceptor secara otomatis meng-cache respons GET menggunakan URL request sebagai key default. Custom cache key berguna ketika beberapa route harus berbagi atau memiliki entri cache yang berbeda. ## Session Management dengan Redis Store Sesi HTTP yang didukung Redis memungkinkan data sesi bertahan di seluruh server restart dan scaling horizontal. Package express-session terintegrasi dengan NestJS melalui middleware. ```bash npm install express-session connect-redis ioredis npm install -D @types/express-session ``` Konfigurasi session store memerlukan instance Redis client. Package ioredis menyediakan dukungan Redis yang lebih baik dengan clustering dan sentinel. ```typescript // main.ts import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import * as session from 'express-session'; import RedisStore from 'connect-redis'; import { Redis } from 'ioredis'; async function bootstrap() { const app = await NestFactory.create(AppModule); const redisClient = new Redis( process.env.REDIS_URL || 'redis://localhost:6379' ); app.use( session({ store: new RedisStore({ client: redisClient }), secret: process.env.SESSION_SECRET || 'your-secret-key', resave: false, saveUninitialized: false, cookie: { secure: process.env.NODE_ENV === 'production', httpOnly: true, maxAge: 24 * 60 * 60 * 1000, // 24 jam sameSite: 'lax', }, }), ); await app.listen(3000); } bootstrap(); ``` Opsi `resave: false` mencegah session disimpan kembali jika tidak dimodifikasi. Pengaturan `saveUninitialized: false` memastikan session kosong tidak memenuhi penyimpanan Redis. ## Mengakses Session Data di Controller Data session tersedia melalui objek request. Custom decorator menyederhanakan akses session di seluruh handler. ```typescript // session.decorator.ts import { createParamDecorator, ExecutionContext } from '@nestjs/common'; export const GetSession = createParamDecorator( (data: string, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); return data ? request.session?.[data] : request.session; }, ); // auth.controller.ts import { Controller, Post, Body, Get } from '@nestjs/common'; import { GetSession } from './session.decorator'; import { Session } from 'express-session'; interface UserSession extends Session { userId?: string; role?: string; loginAt?: Date; } @Controller('auth') export class AuthController { @Post('login') async login( @Body() credentials: LoginDto, @GetSession() session: UserSession, ) { // Validasi credentials const user = await this.authService.validate(credentials); // Simpan data user di session session.userId = user.id; session.role = user.role; session.loginAt = new Date(); return { message: 'Login berhasil' }; } @Post('logout') async logout(@GetSession() session: UserSession) { return new Promise((resolve, reject) => { session.destroy((err) => { if (err) reject(err); resolve({ message: 'Logout berhasil' }); }); }); } @Get('profile') async getProfile(@GetSession('userId') userId: string) { if (!userId) { throw new UnauthorizedException('Session tidak valid'); } return this.usersService.findById(userId); } } ``` ## Cache Invalidation Strategies Strategi invalidasi cache yang tepat menjaga konsistensi data. Pola yang umum termasuk time-based expiration, event-driven invalidation, dan manual purging. ```typescript // cache-invalidation.service.ts import { Injectable, Inject } from '@nestjs/common'; import { CACHE_MANAGER, Cache } from '@nestjs/cache-manager'; import { OnEvent } from '@nestjs/event-emitter'; @Injectable() export class CacheInvalidationService { constructor(@Inject(CACHE_MANAGER) private cache: Cache) {} // Event-driven invalidation @OnEvent('user.updated') async handleUserUpdate(payload: { userId: string }) { await this.cache.del(`user:${payload.userId}`); await this.cache.del('users:list'); } @OnEvent('product.created') async handleProductCreate() { // Invalidate semua cache produk saat produk baru dibuat await this.invalidatePattern('products:*'); } // Pattern-based invalidation memerlukan akses Redis langsung async invalidatePattern(pattern: string): Promise { const store = this.cache.stores[0] as any; const redis = store?.opts?.redis || store?.redis; if (redis) { const keys = await redis.keys(pattern); if (keys.length > 0) { await redis.del(...keys); } } } // Manual cache warming async warmCache(): Promise { const popularProducts = await this.productsService.findPopular(); for (const product of popularProducts) { await this.cache.set(`product:${product.id}`, product, 600000); } } } ``` ## Rate Limiting dengan Redis Redis menyediakan penyimpanan terdistribusi untuk rate limit counter. Package @nestjs/throttler mendukung Redis sebagai backend penyimpanan. ```bash npm install @nestjs/throttler @nestjs/throttler-storage-redis ioredis ``` ```typescript // app.module.ts import { Module } from '@nestjs/common'; import { ThrottlerModule } from '@nestjs/throttler'; import { ThrottlerStorageRedisService } from '@nestjs/throttler-storage-redis'; import { Redis } from 'ioredis'; @Module({ imports: [ ThrottlerModule.forRootAsync({ useFactory: () => ({ throttlers: [ { name: 'short', ttl: 1000, limit: 3, }, { name: 'medium', ttl: 10000, limit: 20, }, { name: 'long', ttl: 60000, limit: 100, }, ], storage: new ThrottlerStorageRedisService( new Redis(process.env.REDIS_URL || 'redis://localhost:6379') ), }), }), ], }) export class AppModule {} ``` ## Pertanyaan Interview: Caching dan Redis di NestJS Berikut adalah pertanyaan interview umum yang menguji pemahaman tentang integrasi Redis dalam aplikasi NestJS. **Pertanyaan 1: Apa perbedaan antara cache-aside dan read-through caching?** Cache-aside mengharuskan kode aplikasi secara eksplisit memeriksa cache dan mengisinya saat cache miss. Read-through caching mendelegasikan proses ini ke cache layer itu sendiri. NestJS cache-manager menggunakan pola cache-aside di mana developer bertanggung jawab atas logika get/set. **Pertanyaan 2: Bagaimana cara menangani cache stampede?** Cache stampede terjadi ketika banyak request secara bersamaan menemukan cache miss dan semuanya query database. Solusinya termasuk request coalescing (mengantri request duplikat), probabilistic early expiration, atau lock-based population di mana hanya satu request yang mengisi cache sementara yang lain menunggu. **Pertanyaan 3: Mengapa menggunakan Redis untuk session daripada session berbasis memori?** Session berbasis memori tidak bertahan saat server restart dan tidak dapat dibagikan antar beberapa instance. Redis memberikan persistensi, horizontal scaling, dan fitur expiration bawaan untuk manajemen session. **Pertanyaan 4: Jelaskan perbedaan antara cache TTL dan sliding expiration?** TTL tetap meng-expire entri pada interval yang ditetapkan sejak pembuatan. Sliding expiration mereset timer setiap kali data diakses. Redis native hanya mendukung TTL tetap; sliding expiration memerlukan logika aplikasi untuk memperbarui waktu expiration saat read. **Pertanyaan 5: Bagaimana cara meng-cache data yang berbeda per user?** Gunakan cache key yang menyertakan user identifier: `user:${userId}:preferences`. Ini memastikan isolasi antara data user yang berbeda sambil tetap mendapatkan manfaat dari caching. **Pertanyaan 6: Apa trade-off antara cache hit rate dan memory usage?** TTL yang lebih tinggi meningkatkan hit rate tetapi mengkonsumsi lebih banyak memori dan berisiko data menjadi stale. TTL yang lebih pendek menjaga data tetap fresh tetapi meningkatkan load database. Solusi optimal menyeimbangkan kedua faktor berdasarkan pola akses dan sensitivitas data. ## Kesimpulan Integrasi Redis dengan NestJS memerlukan pemahaman tentang pola caching, strategi session management, dan pertimbangan konfigurasi. Module @nestjs/cache-manager menyediakan abstraksi yang bersih untuk operasi caching, sementara express-session dengan connect-redis menangani persistensi session. Kombinasi keduanya memungkinkan aplikasi NestJS untuk scaling secara horizontal sambil mempertahankan performa dan state management yang konsisten. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/id/blog/node-nestjs/nestjs-redis-caching-sessions-interview-questions