Redis LRU Cache With TTL Eviction

Build a Redis-backed caching layer with TTL eviction, LRU maxmemory policy, cache-aside reads, and explicit invalidation on writes.

JavascriptNodeData Fetching

Code

snippet
import { createClient } from 'redis';

const redis = createClient({ url: process.env.REDIS_URL ?? 'redis://127.0.0.1:6379' });
redis.on('error', (err) => console.error('redis:', err.message));
await redis.connect();

const TTL_SECONDS = 300;

async function cached(key, loader) {
  const hit = await redis.get(key);
  if (hit !== null) {
    await redis.incr('cache:stats:hits');
    return JSON.parse(hit);
  }
  const fresh = await loader();
  await redis.set(key, JSON.stringify(fresh), { EX: TTL_SECONDS, NX: true });
  await redis.incr('cache:stats:misses');
  return fresh;
}

async function invalidate(prefix) {
  const pattern = prefix + ':*';
  for await (const key of redis.scanIterator({ MATCH: pattern, COUNT: 200 })) {
    await redis.del(key);
  }
}

const product = await cached('product:42', () => fetchProduct(42));
await invalidate('product');
await redis.quit();