Files
2025-11-29 18:22:25 +08:00

2.5 KiB

Cache Invalidation Patterns

Event-Based: Invalidate on Data Changes

Use when: consistency critical, staleness unacceptable.

async function createPost(data: { title: string; content: string; authorId: string }) {
  const post = await prisma.post.create({ data });

  await Promise.all([
    redis.del(`posts:author:${data.authorId}`),
    redis.del('posts:recent'),
    redis.del('posts:popular'),
  ]);

  return post;
}

Time-Based: TTL-Driven Expiration

Use when: staleness acceptable for TTL duration, mutations infrequent.

async function getRecentPosts() {
  const cached = await redis.get('posts:recent');
  if (cached) return JSON.parse(cached);

  const posts = await prisma.post.findMany({
    orderBy: { createdAt: 'desc' },
    take: 10,
  });

  await redis.setex('posts:recent', 300, JSON.stringify(posts));
  return posts;
}

Hybrid: TTL + Event-Based Invalidation

Use when: mutations trigger immediate invalidation, TTL provides safety net.

async function updatePost(postId: string, data: { title?: string }) {
  const post = await prisma.post.update({
    where: { id: postId },
    data,
  });
  await redis.del(`post:${postId}`);
  return post;
}

async function getPost(postId: string) {
  const cached = await redis.get(`post:${postId}`);
  if (cached) return JSON.parse(cached);

  const post = await prisma.post.findUnique({
    where: { id: postId },
  });
  if (post) await redis.setex(`post:${postId}`, 600, JSON.stringify(post));
  return post;
}

Strategy Selection by Data Characteristics

Characteristic Approach
Changes >1/min Avoid caching or use 5-30s TTL; consider real-time updates; event-based invalidation for consistency
Changes rare (hours/days) Use 5-60min TTL; event-based invalidation on mutations; warm cache on startup
Read/write ratio >10:1 Strong cache candidate; cache-aside pattern; warm popular data in background
Read/write ratio <3:1 Weak candidate; optimize queries instead; cache only if DB bottlenecked
Consistency required Short TTL + event-based invalidation; cache-through/write-behind patterns; add versioning for atomic updates