Urgent.News

What's breaking now, across thousands of outlets.

Tech

Next.js use cache, cacheLife and cacheTag: How One View Counter Rebuilt Every Page

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…

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.

To 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.

To 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.

The 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.

To 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.

By 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.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Packed vs Holey Arrays in V8: Why new Array(n) Makes Spread 4x Slower

Two arrays. Same million numbers, in the same order, with no gaps in either: const a = [ ] ; for ( let i = 0 ; i < 1_000_000 ; i ++ ) a .

  • Packed arrays copy faster than holey arrays in V8
  • Spread syntax copies million-element packed array in 0.17ms
  • Holey arrays take 0.71ms to copy same million elements

More from Wednesday 11 November →