AI Skill Library

Caching Strategies

HTTP cache, CDN, Redis, stale-while-revalidate, cache invalidation patterns.

performancebackendcachingweb
# Caching Strategies

## HTTP Cache headers
```
# Immutable static assets (hashed filenames)
Cache-Control: public, max-age=31536000, immutable

# API responses (revalidate after 60s)
Cache-Control: public, max-age=0, s-maxage=60, stale-while-revalidate=300

# Private user data
Cache-Control: private, no-cache

# Never cache
Cache-Control: no-store
```

## ETag / Conditional requests
```js
// Server
const etag = crypto.createHash('md5').update(body).digest('hex')
res.setHeader('ETag', `"${etag}"`)
if (req.headers['if-none-match'] === `"${etag}"`) {
  return res.status(304).end()
}
```

## Redis caching pattern
```ts
async function getCached<T>(key: string, ttl: number, fetcher: () => Promise<T>): Promise<T> {
  const cached = await redis.get(key)
  if (cached) return JSON.parse(cached)
  const data = await fetcher()
  await redis.setex(key, ttl, JSON.stringify(data))
  return data
}

// Usage
const user = await getCached(`user:${id}`, 300, () => db.user.findUnique({ where: { id } }))
```

## Cache invalidation patterns
1. **TTL-based**: Set expiry, accept staleness. Simplest.
2. **Write-through**: Update cache on every write.
   ```ts
   async function updateUser(id, data) {
     const user = await db.user.update({ where: { id }, data })
     await redis.setex(`user:${id}`, 300, JSON.stringify(user))
     return user
   }
   ```
3. **Write-behind**: Queue cache writes, batch to DB.
4. **Event-driven**: Pub/Sub invalidation on data change.

## CDN caching
- Use `s-maxage` for CDN TTL (independent of browser `max-age`).
- `stale-while-revalidate`: serve stale, refresh in background.
- Purge API: `curl -X POST https://api.cdn.com/purge -d '{"url":"..."}'`
- Cache key: URL + Vary headers (Accept-Language, etc.).

## SWR in frontend (React)
```tsx
import useSWR from 'swr'
const { data, error, isLoading, mutate } = useSWR('/api/user', fetcher, {
  revalidateOnFocus: false,
  dedupingInterval: 5000,
})
// Optimistic update
mutate(updatedData, { optimisticData: updatedData, revalidate: true })
```

## Anti-patterns
- Caching without invalidation strategy → stale bugs.
- Caching errors or empty responses → amplified failures.
- Cache stampede: use lock/singleflight when cache expires.

API: /api/skills/caching-strategies