Redis Store for node-cache-manager
cache-manager-redis-store is a dedicated Redis store for the `node-cache-manager` library, providing a performant and reliable caching layer for Node.js applications. The current stable version is 3.0.1, released in October 2022. It generally follows an irregular release cadence, often aligning with major dependency updates or critical bug fixes. This package differentiates itself from older alternatives like `node-cache-manager-redis` by avoiding the `redis-pool` library, instead offering a simpler wrapper that directly passes configuration to the underlying `redis` client (upgraded to `redis@^4` in v3.0.0). It aims to provide a straightforward integration for Redis caching within the `node-cache-manager` ecosystem, with robust support for both single and multi-store caching setups. The library also provides TypeScript types, enhancing the developer experience for TypeScript projects.
Common errors
-
TypeError: store.create is not a function
cause Attempting to pass the `cache-manager-redis-store` factory function directly to `cacheManager.caching()` when using `cache-manager` v4.x or higher, which expects an already instantiated store object or an object with a `create` method.fixEnsure you call the `redisStore` factory function to get an instance before passing it: `const myRedisStore = redisStore(options); const cache = caching({ store: myRedisStore });` -
ERR_MODULE_NOT_FOUND: Cannot find package 'cache-manager-redis-store' imported from ...
cause This error typically occurs when trying to `require()` an ESM-only package or `import` a CommonJS-only package. While this package ships types, its core export behavior might lead to issues in mixed environments.fixFor ESM projects, use `import redisStore from 'cache-manager-redis-store';`. For CommonJS, use `const redisStore = require('cache-manager-redis-store');`. Ensure your `tsconfig.json` (for TypeScript) or Node.js environment is configured correctly for module resolution. -
Error: connect ECONNREFUSED <ip-address>:<port>
cause The Redis client failed to connect to the specified Redis server. This could be due to the Redis server not running, incorrect host/port configuration, or firewall issues.fixVerify that your Redis server is running and accessible from your application's host. Double-check the `host` and `port` values in your `redisStore` options. Ensure no firewalls are blocking the connection.
Warnings
- breaking Version 3.0.0 upgraded the underlying Redis client to `redis@^4`. This version of `redis` is entirely promise-based, deprecating callback-style APIs. Ensure your `cache-manager` version is compatible (typically v4.x or newer) and update your code to use async/await or `.then()` for cache operations.
- breaking Since v3.0.0, the Redis store must be explicitly instantiated *before* being passed to `cacheManager.caching()`. You can no longer pass the factory function directly and expect `cache-manager` to instantiate it internally. The `store` option for `caching()` should receive an *instance* of the store, e.g., `store: redisStore(options)` instead of `store: redisStore`.
- breaking Support for Node.js versions older than 16.18 was dropped in v3.0.0. Running this package on older Node.js environments will result in runtime errors.
- breaking In v2.0.0, the `set` method was updated to strictly check `isCacheableValue` before storing a value. This means `null` or `undefined` values might no longer be cached, potentially altering behavior for applications that relied on caching such values.
- gotcha This package (`cache-manager-redis-store`) is a completely separate and actively maintained project from the older `node-cache-manager-redis`. It uses a simpler wrapper and `redis@^4` directly, avoiding `redis-pool`. If migrating, expect API differences and breaking changes.
- gotcha A bug in v3.0.0 prevented the `redisStore.del` method from correctly accepting an options object, which particularly impacted the `multiCaching` interface where `del` operations might not propagate correctly across all caches. This was fixed in v3.0.1.
Install
-
npm install cache-manager-redis-store -
yarn add cache-manager-redis-store -
pnpm add cache-manager-redis-store
Imports
- redisStore
import { redisStore } from 'cache-manager-redis-store';import redisStore from 'cache-manager-redis-store';
Quickstart
import { caching, multiCaching } from 'cache-manager';
import redisStore from 'cache-manager-redis-store';
// Configure Redis client options (e.g., host, port, password)
const redisOptions = {
host: process.env.REDIS_HOST ?? 'localhost',
port: parseInt(process.env.REDIS_PORT ?? '6379', 10),
password: process.env.REDIS_PASSWORD ?? '', // Use environment variables for sensitive info
db: 0,
ttl: 600, // Default TTL in seconds
};
async function initializeAndUseCache() {
// Create an instance of the Redis store
const redisCacheStore = redisStore(redisOptions);
// Initialize a single cache manager with the Redis store instance
const redisCache = caching({ store: redisCacheStore, ttl: 600 });
// Listen for Redis connection errors
// Note: For redis@^4, client events might be handled differently,
// often through the client instance returned by `redisCacheStore.getClient()`.
const redisClient = await redisCacheStore.getClient();
redisClient.on('error', (error: Error) => {
console.error('Redis Client Error:', error);
});
// Set a value
await redisCache.set('foo', 'bar', 5); // TTL of 5 seconds
console.log('Set foo to bar with TTL 5s');
// Get a value
const result = await redisCache.get('foo');
console.log(`Get foo: ${result}`); // Expected: 'bar'
// Wrap: fetches from cache, or executes function and caches result
async function getSlowUser(id: number) {
console.log(`Returning user ${id} from slow database.`);
return new Promise(resolve => setTimeout(() => resolve({ id, name: `User ${id}` }), 100));
}
const userId = 123;
const userKey = `user_${userId}`;
const user1 = await redisCache.wrap(userKey, () => getSlowUser(userId), { ttl: 10 });
console.log('Wrapped user (first call):', user1); // Logs 'Returning user from slow database.'
const user2 = await redisCache.wrap(userKey, () => getSlowUser(userId), { ttl: 10 });
console.log('Wrapped user (second call):', user2); // Fetches from cache, no 'slow database' log
// --- Multi-store caching ---
const memoryCacheStore = caching({ store: 'memory', max: 100, ttl: 60 });
const multiCache = multiCaching([memoryCacheStore, redisCache]);
const multiUserKey = 'multiUser_456';
const multiUser = await multiCache.wrap(multiUserKey, () => getSlowUser(456), { ttl: 15 });
console.log('Multi-cache wrapped user (first call):', multiUser);
// Subsequent calls fetch from the highest priority cache (memoryCacheStore)
const multiUser2 = await multiCache.wrap(multiUserKey, () => getSlowUser(456), { ttl: 15 });
console.log('Multi-cache wrapped user (second call):', multiUser2);
// Clean up
await redisCache.del('foo');
await redisCache.del(userKey);
await multiCache.del(multiUserKey);
console.log('Cleaned up cache entries.');
}
initializeAndUseCache().catch(console.error);