Caching information in Redis on NestJS
Publication date: 2024-11-20
Each frontend request to the backend requests user profile information from the database, this creates an additional load on the database and increases the backend response time, to speed up such requests, you can cache the database response.
In this post, I will connect Redis to the project and set up data caching via @nestjs-mod/cache-manager.
The project can be run in Docker Compose and Kubernetes.
1. Install additional libraries
Install JS-client and NestJS-module for working with cache-manager and Redis.
Commands
npm install --save redis cache-manager-redis-yet cache-manager @nestjs-mod/cache-manager
$ npm install --save redis cache-manager-redis-yet cache-manager @nestjs-mod/cache-manager
npm warn deprecated cache-manager-redis-yet@5.1.5: With cache-manager v6 we now are using Keyv
added 17 packages, removed 2 packages, and audited 2934 packages in 19s
360 packages are looking for funding
run `npm fund` for details
41 vulnerabilities (19 low, 7 moderate, 15 high)
To address issues that do not require attention, run:
npm audit fix
To address all issues possible (including breaking changes), run:
npm audit fix --force
Some issues need review, and may require choosing
a different dependency.
Run `npm audit` for details.
2. Connecting new modules to the backend
Updating the file apps/server/src/main.ts
import {
DOCKER_COMPOSE_FILE,
DockerCompose,
DockerComposeAuthorizer,
DockerComposeMinio,
DockerComposePostgreSQL,
} from '@nestjs-mod/docker-compose';
// ...
import { MinioModule } from '@nestjs-mod/minio';
// ...
import { ExecutionContext } from '@nestjs/common';
// ...
bootstrapNestApplication({
modules: {
// ...
core: [
CacheManagerModule.forRoot({
staticConfiguration: {
type: isInfrastructureMode() ? 'memory' : 'redis',
},
}),
],
infrastructure: [
DockerComposeMinio.forRoot({
staticConfiguration: { image: 'bitnami/minio:2024.11.7' },
}),
]}
);
3. We are starting the generation of additional code for the infrastructure
Commands
npm run docs:infrastructure
After running, a new service server-redis will appear in the docker-compose file and a new environment variable SERVER_REDIS_URL will appear in the environment variable, which needs to be filled.
Updated file apps/server/docker-compose-prod.yml
server-redis:
image: 'bitnami/redis:7.4.1'
container_name: 'server-redis'
volumes:
- 'server-redis-volume:/bitnami/redis/data'
ports:
- '6379:6379'
networks:
- 'server-network'
environment:
REDIS_DISABLE_COMMANDS: '${SERVER_REDIS_REDIS_DISABLE_COMMANDS}'
REDIS_IO_THREADS: '${SERVER_REDIS_REDIS_IO_THREADS}'
REDIS_IO_THREADS_DO_READS: '${SERVER_REDIS_REDIS_IO_THREADS_DO_READS}'
healthcheck:
test:
- 'CMD-SHELL'
- 'redis-cli ping | grep PONG'
interval: '5s'
timeout: '5s'
retries: 5
tty: true
restart: 'always'
Updating the file .env
# ...
SERVER_REDIS_URL=redis://:CHmeOQrZWUHwgahrfzsrzuREOxgAENsC@localhost:6379
We re-run the generation of additional code for the infrastructure to generate additional environment variables.
Commands
npm run docs:infrastructure
Updated file apps/server/docker-compose-prod.yml
server-redis:
image: 'bitnami/redis:7.4.1'
container_name: 'server-redis'
volumes:
- 'server-redis-volume:/bitnami/redis/data'
ports:
- '6379:6379'
networks:
- 'server-network'
environment:
REDIS_DATABASE: '${SERVER_REDIS_REDIS_DATABASE}'
REDIS_PASSWORD: '${SERVER_REDIS_REDIS_PASSWORD}'
REDIS_DISABLE_COMMANDS: '${SERVER_REDIS_REDIS_DISABLE_COMMANDS}'
REDIS_IO_THREADS: '${SERVER_REDIS_REDIS_IO_THREADS}'
REDIS_IO_THREADS_DO_READS: '${SERVER_REDIS_REDIS_IO_THREADS_DO_READS}'
healthcheck:
test:
- 'CMD-SHELL'
- 'redis-cli --no-auth-warning -a $$REDIS_PASSWORD ping | grep PONG'
interval: '5s'
timeout: '5s'
retries: 5
tty: true
restart: 'always'
4. We launch the infrastructure with applications in development mode and check it through E2E tests
Commands
npm run pm2-full:dev:start
npm run pm2-full:dev:test:e2e