{
  "id": 19477840,
  "title": "Next.js use cache, cacheLife and cacheTag: How One View Counter Rebuilt Every Page",
  "url": "https://urgent.news/2026/11/11/next-js-use-cache-cachelife-and-cachetag-how-one-view-counter-rebuilt",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-11-11T09:55:36.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/mohsenfallahnjd/nextjs-use-cache-cachelife-and-cachetag-how-one-view-counter-rebuilt-every-page-1loo"
  },
  "original_language": "en",
  "account": "A developer found that a blog's use of cached view counts was causing all pages to refresh every 5 minutes, even though the data only changed when new posts were added. The issue stemmed from a line in the code that read `const stats = await getPostStats(); // read + comment counts, cached for 5 minutes`. This line caused the cached data to expire every 5 minutes, leading to stale content on various pages.\n\nTo address this, the developer likened the server cache to a shared fridge, where each visitor shares the same set of results. They introduced the `use cache` directive, which stores the result of a function or component and reuses it for subsequent requests. The `cacheLife` parameter determines how long the cached data remains fresh before being refreshed in the background. The developer used `cacheLife(max)` to set the cache expiration to the maximum duration.\n\nTo fine-tune the caching behavior, the developer introduced the `cacheTag` parameter, which allows them to invalidate specific cached entries when the underlying data changes. They created a `cacheTag` for comments and used it with the `revalidateTag` function to invalidate the cache when new comments were added. Additionally, they used `updateTag` in a server action to refresh the cache immediately when a comment is approved.\n\nThe developer also pointed out that TanStack Query, a separate caching library for client-side data, should be used in conjunction with server cache. While server cache is suitable for shared data that doesn't change frequently, TanStack Query offers more granular control over per-user data, such as carts and dashboards. They recommend using server cache for data that changes only when new content is deployed, and TanStack Query for live or per-user data that requires real-time updates.\n\nTo implement this approach, the developer placed the cached data on the server and fetched live or per-user data on the client-side using a route handler. They connected the `useQuery` hook from TanStack Query to the server's cached data and configured it with a `staleTime` parameter that matched the server's refresh time. When the user modifies data, the developer clears both the server cache and the TanStack Query cache by using the `updateTag` function in the server action and `queryClient.invalidateQueries` in the browser.\n\nBy following these steps, the developer was able to drastically improve the performance of their blog. Instead of refreshing every 5 minutes, the pages now updated only when new posts were added, reducing the build output time from every 5 minutes to every 1 day. This optimization ensured that the blog remained fast and efficient while still providing up-to-date content for users.",
  "summary": "Vercel's usage page told me this blog had used 2 h 32 min of function CPU in 30 days: 80% of everything on my account. It's a blog. The posts only change when I deploy. The cause was one line near the top of my pages: const stats = await getPostStats ( ) ; // read + comment counts, cached for 5 minutes The counts were cached for 5 minutes. But the 5-minute timer didn't stay on the counts. Every…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}