Build the mental model
A production cache wrapper centralizes serialization, timeouts, key versions, TTL jitter, metrics, and error policy. Callers receive typed values or null without knowing Redis details. Separate cache errors from database errors and observe hits, misses, errors, and load latency.
Connect it to a real scenario
Using a Node.js Redis client, write a generic `getOrLoad<T>` helper. Delete malformed cached values, protect loaders with a bounded single-flight lock, and invalidate after database update commits. Integration-test hit, miss, expiry, update, and Redis-down cases.
Try the working example
async function getOrLoad<T>(key: string, load: () => Promise<T | null>) {
try {
const hit = await redis.get(key);
if (hit) return JSON.parse(hit) as T;
} catch (error) { metrics.cacheError.inc(); }
const value = await load();
if (value) await redis.set(key, JSON.stringify(value), { EX: 300 + randomInt(30) });
return value;
}You get a typed catalog service that remains correct when cache is unavailable.5-minute try-it
Add 15-second negative caching for missing tutorials and test create-after-miss behavior.
One important caution
If the Redis timeout consumes the HTTP deadline, no time remains for fallback; keep cache timeouts short.
Redis — Node.js Client Guide — Redis