@dataweavers/redis-cache-store
v0.0.2
Published
Allows customer implementations to use Redis as a centralised cache store for custom data storage.
Downloads
127
Readme
Dataweavers - Redis Cache Store
Provides a standardised Redis caching integration for custom data caching needs, designed for Next.js applications. On install, the package automatically copies the necessary source files into your project. All usage is of the cache handler is done on via custom code, i.e. you utilise the store where you need it.
What this is
A Redis caching solution that can be used with the Dataweavers Arc platform for customers to store limited data sets across shared a many instance application as and when required.
What this isn't
A one solution fits all use cases. There are other caching packages available and other caching mechanisms for your next.js application. This is an implementation to enable your application to utilise the Redis resource for caching in next.js.
Features
- Custom cache-store module – A programmatic cache module (
createCacheStore) for application-level caching with Redis + LRU fallback support. Single prefix per process.
Installation
npm install @dataweavers/redis-cache-store redisNote: This package requires
redisas a peer dependency. Please ensure you also install theredispackage (^5.6.1) in your consumer application, as shown above.
The postinstall script runs automatically and copies the following into your project:
| Source (inside package) | Destination (in your project) |
|---|---|
| copy-content/source-root/lib/custom-cache/index.ts | src/lib/custom-cache/index.ts |
Configuration
The following environment variables are available to tweak and
| Variable | Required | Default | Description |
|---|---|---|---|
| REDIS_URL | Yes | (empty) | Connection URL for the Redis instance, e.g. redis://localhost:6379. Leave blank for local development to fall back to LRU. |
| REDIS_ACCESS_KEY | No | (empty) | Access key / password for the Redis instance (e.g. Azure Cache for Redis). |
| CACHE_STORE_PREFIX | No | dw-cc | Root prefix for cache-store keys. Used for all cache-store set/get/scan/delete/clear operations. Fixed per process; set at startup via environment variable. |
| CACHE_STORE | No | lru | Cache-store mode for custom caching. Supported values: lru, redis. |
| LRU_MAX_SIZE | No | 500 | Maximum number of entries in the cache-store LRU cache. |
| REDIS_MIN_TTL_SECONDS | No | 30 | Minimum allowed TTL (seconds) for cacheStore.set(..., ttl). |
| REDIS_MAX_TTL_SECONDS | No | 86400 | Maximum allowed TTL (seconds) for cacheStore.set(..., ttl). |
| REDIS_MEM_LIMIT_BYTES | No | 524288000 | Soft memory cap for cache-store Redis data, used by its LRU-style eviction logic. |
| REDIS_MEM_RECONCILE_INTERVAL_MS | No | 300000 | How often cache-store reconciles Redis metadata and memory accounting. Minimum: 60000ms. |
| CACHE_MANAGEMENT_SECRET | No | (must be set) | Secret key used to authenticate requests to the cache management API routes i.e. /api/clear-custom-cache if used. Use a strong random string. |
| CACHE_POPULATE_BATCH_SIZE | No | 25 | Number of pages processed per batch during cache population. |
| CACHE_POPULATE_BATCH_DELAY_MS | No | 5000 | Delay in milliseconds between batches during cache population. |
| DATAWEAVERS_LOG_LEVEL | No | error | Log verbosity. Options: silent, error, warn, info, debug, trace. |
Dataweavers recommends that you store the secrets/keys in a secure vault rather than a variable file.
Example - Using the cache-store module (custom caching)
The package also exports a programmatic cache module for application-level caching.
import { getCacheStore } from 'lib/_platform/cache/custom-cache';
const cacheStore = getCacheStore();
const key = 'product:123';
await cacheStore.set(key, { id: 123, name: 'Sample' }, 300);
const cached = await cacheStore.get(key);
if (cached.success && cached.data) {
return cached.data;
}cacheStore.set(..., ttl) validates TTL against env-configured bounds: REDIS_MIN_TTL_SECONDS (default 30) and REDIS_MAX_TTL_SECONDS (default 86400, 1 day). Values outside this range return a failed operation result.
Initial Setup - copied to codebase on install
The package install will copy a file "\lib_platform\cache\custom-cache.ts" into the solution. This utilises a singleton pattern for access to the cache. Once added, the install/upgrade of the npm package again will not overwrite the changes. Whilst we recommend against making changes to the implementation customisations will not be overwritten.
/* eslint-disable */
import { CacheStoreMode, createCacheStore, type ICacheStore } from "@dataweavers/redis-cache-store";
declare global {
// eslint-disable-next-line no-var
var __dwCacheStore: ICacheStore | undefined;
}
export function getCacheStore(): ICacheStore {
if (!globalThis.__dwCacheStore) {
globalThis.__dwCacheStore = createCacheStore({ mode: CacheStoreMode.REDIS, });
}
return globalThis.__dwCacheStore;
}
/* eslint-enable */When to initialise
Initialise the cache-store once per process, not per request.
- Initialise at module scope in a shared server-only module.
- Reuse the same instance in services, API routes, server actions, or background jobs.
- Do not create a new
createCacheStore()instance inside request handlers on every call.
Creating new instances repeatedly can open extra Redis clients and schedule extra reconcile timers.
Example - Enabling a cache clear API endpoint
Create a new file into the next.js API directory and copy in the following code.
import { CacheClear } from '@dataweavers/nextjs-redis-caching';
const handler = new CacheClear(process.env.CACHE_MANAGEMENT_SECRET || '').getHandler();
export default handler;
This API endpoint is used if external cache clearing is required. The endpoint allows cache clearing by key pattern.
Example uses:
- A deployment changes the shape of cached payloads.
- A content or data migration invalidates existing custom cache values.
- You need an operational recovery path for stale or bad custom-cache entries.
The endpoint is secured by CACHE_MANAGEMENT_SECRET and supports both full and scoped clears.
POST /api/clear-custom-cache?secret=your-strong-random-secret-key
POST /api/clear-custom-cache?secret=your-strong-random-secret-key&pattern=product:*Notes:
- This endpoint is for cache-store only (custom caching), not Next.js page cache keys.
- Prefer
patternclears first (for exampleproduct:*) and reserve full clears for incident/release operations.
Edge cases and runtime constraints
- Use cache-store on the server only. Do not call
createCacheStore()orgetCacheStore()from Client Components or other browser code, because the store depends on server runtime capabilities (Redis/network access, Node APIs, and server-side secrets) that must not be exposed to browser bundles. - Preferred usage points are Server Components, Route Handlers, API routes, server actions, and background jobs.
- Values are serialised with
superjsonin both Redis and LRU modes. This preserves many non-JSON types (for exampleDate,Map,Set, andBigInt). - Still prefer caching plain data objects for cross-boundary safety. Avoid caching runtime-bound values such as functions, class instances with behaviour, streams, database clients, or React elements.
- The package serialises on write (
set) and deserialises on read (get) for cache-store operations. Metadata loss risk appears when data crosses your own plain-JSON boundaries before write or after read (for example request/response DTOs,JSON.stringify, or systems that only support standard JSON), so treat cross-boundary payloads as plain data. setTTL must be an integer withinREDIS_MIN_TTL_SECONDSandREDIS_MAX_TTL_SECONDS(defaults:30to86400).
Modes and fallback behaviour
CACHE_STORE=lru: in-memory only.CACHE_STORE=redis: Redis is primary and LRU is fallback.- In
redismode, the store switches to LRU after repeated Redis failures and recovers back to Redis when healthy.
Key namespacing and separation from page caching
Page caching and cache-store use separate key roots.
- Page cache keys use
REDIS_KEY_PREFIXdirectly, for examplenextjs:.... - Cache-store Redis keys use
CACHE_STORE_PREFIX, for exampledw-cc:data:product:123. - This ensures cache-store clears/deletes are restricted to cache-store keys and cannot target page-cache keys.
Common operations
// set with ttl (seconds)
await cacheStore.set('article:42', { title: 'Hello' }, 120);
// get
const result = await cacheStore.get('article:42');
// delete one
await cacheStore.del('article:42');
// delete by pattern
await cacheStore.delPattern('article:*');
// clear all cache-store data
await cacheStore.clear();
// health check
const health = await cacheStore.isHealthy();Shutdown guidance
Call disconnect() during controlled shutdown for long-running Node processes.
await cacheStore.disconnect();