DEV Community

Atlas Whoff
Atlas Whoff

Posted on

API Caching Strategies: TTL, Stale-While-Revalidate, and Invalidation

API Caching Strategies: TTL, Stale-While-Revalidate, and Invalidation

There are two hard problems in computer science: cache invalidation and naming things.

Strategy 1: Simple TTL

async function getProduct(id: string): Promise<Product> {
  const cached = await redis.get(`product:${id}`);
  if (cached) return JSON.parse(cached);

  const product = await db.products.findUnique({ where: { id } });
  await redis.setex(`product:${id}`, 300, JSON.stringify(product)); // 5min TTL
  return product;
}
Enter fullscreen mode Exit fullscreen mode

Good for data that can tolerate slight staleness. Bad for real-time data.

Strategy 2: Stale-While-Revalidate

Serve stale data immediately, refresh in background. Users get instant response, data is almost always fresh.

// HTTP header version
res.set('Cache-Control', 'public, max-age=60, stale-while-revalidate=300');
Enter fullscreen mode Exit fullscreen mode

Strategy 3: Event-Based Invalidation

async function updateProduct(id: string, updates: Partial<Product>) {
  const updated = await db.products.update({ where: { id }, data: updates });

  // Invalidate all related keys immediately
  await Promise.all([
    redis.del(`product:${id}`),
    redis.del(`category:${updated.categoryId}:products`),
    redis.del('products:featured'),
  ]);

  return updated;
}
Enter fullscreen mode Exit fullscreen mode

Good for data that must be immediately consistent after writes.

MCP and Caching

MCP tool calls happen frequently in AI workflows — external rate limits are brutal without caching. The Workflow Automator MCP includes built-in Redis caching for all external API calls.

Top comments (0)