The shape of the metadata object associated with each cache entry
Creates a new instance of the RedisCacheStore.
The configuration options for the RedisCacheStore
The maximum size (in bytes) allowed for a single cache entry. Must be a non-negative integer. Defaults to 100MB
A callback function to handle errors that occur during Redis operations
Options to configure the underlying Redis client. May include keyPrefix and other Redis client options
Prefix to apply to all Redis keys for namespacing
The maximum number of entries allowed in the tracking cache (only used when tracking is enabled)
If set to false, disables the local tracking cache. Defaults to true
const store = new RedisCacheStore({
clientOpts: { host: 'localhost', port: 6379 }
});
const store = new RedisCacheStore<MyMetadata>({
maxEntrySize: 50 * 1024 * 1024, // 50MB
maxCount: 5000, // Track up to 5000 entries locally
tracking: true, // Enable local tracking (default)
clientOpts: {
host: 'redis.example.com',
port: 6380,
keyPrefix: 'myapp:',
retryDelayOnFailover: 100
},
errorCallback: (err) => {
logger.error('Redis cache error:', err);
metrics.increment('redis.errors');
}
});
Closes the Redis connections used by the cache store.
This method ensures graceful shutdown by:
quit() on all Redis clients (main and subscriber)Once closed, the store instance should not be used for further operations. It's recommended to call this method when your application shuts down or when you're done with the cache store to prevent connection leaks.
A promise that resolves when all connections are closed
process.on('SIGTERM', async () => {
console.log('Shutting down gracefully...');
await store.close();
console.log('Cache store closed');
process.exit(0);
});
const server = express();
const store = new RedisCacheStore(options);
// ... use store in routes ...
server.listen(3000, () => {
console.log('Server started');
});
process.on('SIGINT', async () => {
console.log('Closing server...');
await store.close(); // Close cache before server
server.close();
});
Deletes a cache entry and its associated metadata from Redis.
This method performs a complete cleanup by:
The operation is atomic - either both keys are deleted or neither is. If the metadata doesn't exist, the method returns silently without error.
The cache key to delete
A promise that resolves when the deletion is complete
InternalRetrieves a value and its associated metadata from Redis by the provided key.
This is the core lookup method that handles the Redis-level operations. It performs the following steps:
HGETALLThe key to look up in the cache
A promise that resolves to an object containing the value and its metadata, or undefined if the key is not found or an error occurs
// Scenario 1: Metadata exists but value expired
// Action: Delete stale metadata, return undefined
// Scenario 2: Metadata JSON is corrupted
// Action: Delete both metadata and value, log error, return undefined
// Scenario 3: Redis connection error
// Action: Call error callback, return undefined
Retrieves a cached value and its associated metadata by key.
This method implements a two-tier lookup strategy:
The method handles various edge cases including:
The cache key to retrieve
A promise that resolves to an object containing the value and metadata if found, or undefined if the key does not exist or an error occurs
const result = await store.get('user:123');
if (result) {
console.log('User data:', result.value);
console.log('Metadata:', result.metadata);
} else {
console.log('User not found in cache');
}
interface UserMetadata {
lastUpdated: number;
version: string;
}
const store = new RedisCacheStore<UserMetadata>();
const result = await store.get('user:123');
if (result) {
// TypeScript knows metadata has lastUpdated and version
console.log('Last updated:', new Date(result.metadata.lastUpdated));
console.log('Version:', result.metadata.version);
}
Stores a value in the Redis cache with associated metadata and an optional time-to-live (TTL).
This method performs atomic storage using Redis pipelines to ensure consistency. The operation includes:
maxEntrySizemetadata:[key] → { metadata: JSON, id: UUID } [TTL: ttl seconds]
values:[UUID] → value [TTL: ttl seconds]
The cache key under which the value will be stored
The value to store; must be a string or Buffer
Metadata object to associate with the cache entry. Defaults to empty object if not provided
Time-to-live in seconds; must be a non-negative integer. If not provided, entries will not expire
A promise that resolves when the value and metadata have been stored successfully
await store.set('user:123', JSON.stringify(userData), {
userId: '123',
lastUpdated: Date.now()
});
await store.set('session:abc', sessionData, {
sessionId: 'abc',
createdAt: Date.now()
}, 3600); // Expires in 1 hour
A Redis-backed cache store with optional local tracking and metadata support.
RedisCacheStoreprovides a high-level interface for storing, retrieving, and deleting cache entries in Redis, with support for per-entry metadata, maximum entry size enforcement, and optional local in-memory tracking for improved performance and cache invalidation.Key Features
Architecture Details
The store uses a two-key approach in Redis:
metadata:[key]- Hash containing JSON metadata and a UUIDvalues:[uuid]- String containing the actual cached valueThis design allows for efficient metadata queries without loading large values, and enables atomic cleanup of both parts when entries expire.
Performance Characteristics
Since
1.0.0