# Feed Caching & Staleness

- **Pattern:** `ab-000769` (`community-social-engagement.activity-feeds.feed-caching-strategy`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000769
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000769)

## Why it matters

A feed endpoint with no `Cache-Control` header or client-side `staleTime` triggers a full database query on every page visit, every back-navigation, and every tab focus. For a social feed, this means re-fetching 20 posts with author joins and like counts every few seconds per active user — a multiplier that kills database throughput under modest concurrent load. ISO 25010:2011 performance-efficiency requires that repeated reads of slowly-changing data not incur full round-trip costs each time. Without cache invalidation on post creation, you also risk serving stale feeds, but that is a secondary concern relative to the cost of zero caching.

## Severity rationale

Low because the impact accumulates gradually with user count and does not cause correctness failures, but the fix is low-effort and the cost of omission scales linearly with engagement.

## Remediation

Add a short `stale-while-revalidate` cache header to the feed API response, and configure `staleTime` on the client-side query so back-navigation reuses cached data rather than re-fetching.

```ts
// app/api/feed/route.ts
export async function GET(req: Request) {
  const feed = await getFeed(getCurrentUserId())

  return Response.json(feed, {
    headers: {
      'Cache-Control': 'private, max-age=30, stale-while-revalidate=120'
    }
  })
}

// hooks/useFeed.ts
export function useFeed() {
  return useQuery({
    queryKey: ['feed'],
    queryFn: () => fetch('/api/feed').then(r => r.json()),
    staleTime: 60 * 1000,    // treat data as fresh for 60s
    gcTime: 10 * 60 * 1000  // keep in cache for 10 min
  })
}

// After creating a post, invalidate so the new item appears
queryClient.invalidateQueries({ queryKey: ['feed'] })
```

## Detection

- **ID:** `feed-caching-strategy`
- **Severity:** `low`
- **What to look for:** Enumerate all relevant files and Examine the feed endpoint or server action for caching headers or client-side caching strategy. Look for: (a) HTTP cache headers (`Cache-Control`, `ETag`), (b) client-side caching (React Query/SWR with appropriate stale times), or (c) edge caching (Vercel, Cloudflare). Verify that the feed doesn't refetch entirely when navigating back to a page.
- **Pass criteria:** No more than 0 violations are acceptable. Feed responses include caching directives or the client-side query has `staleTime` configured. Feed data is reused when returning to a page (not re-fetched immediately). Cache invalidation logic exists when new posts are posted.
- **Fail criteria:** No caching strategy, or feeds refetch completely on every page navigation.
- **Skip (N/A) when:** Feed is small and refetching is not a concern.
- **Detail on fail:** `"GET /api/feed has no Cache-Control headers — feed refetches on every back navigation"` or `"useQuery on feed has staleTime 0; data is immediately stale"`
- **Remediation:** Implement feed caching:

  ```ts
  // API route with cache headers
  export async function GET(req: Request) {
    const feed = await getFeed(userId)

    return Response.json(feed, {
      headers: {
        'Cache-Control': 'public, max-age=60, stale-while-revalidate=300',
        'ETag': hashFeed(feed)
      }
    })
  }

  // Client-side caching
  export function useFeed() {
    return useQuery({
      queryKey: ['feed'],
      queryFn: fetchFeed,
      staleTime: 5 * 60 * 1000, // 5 minutes
      gcTime: 30 * 60 * 1000 // 30 minutes
    })
  }

  // Invalidate on post creation
  export async function createPost(content: string) {
    const post = await fetch('/api/posts', { method: 'POST', body: JSON.stringify({ content }) })
    queryClient.invalidateQueries({ queryKey: ['feed'] })
    return post.json()
  }
  ```

## External references

- iso-25010 performance-efficiency

Taxons: performance, cost-efficiency

HTML version: https://auditbuffet.com/patterns/ab-000769
