Cache issue in Next JS 15 with App Router #86538
Replies: 2 comments
-
|
The inconsistent data you are seeing after 1. Server-side fetch/route cacheThis is what 2. Client-side Router Cache (in-memory)This is the culprit. Next.js keeps an in-memory cache of RSC payloads in the browser for pages the user has already visited. Even after the server has fresh data, the browser may serve the previously cached page RSC payload on navigation — without hitting the server at all. This explains:
FixConfigure // next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
experimental: {
staleTimes: {
static: 30, // seconds — was 300 (5 min) by default
dynamic: 0, // seconds — keep at 0 for dynamic routes
},
},
};
export default nextConfig;Alternatively, if a page shows content that changes after mutations (like your post list and post detail), call import { useRouter } from "next/navigation";
const router = useRouter();
async function handlePublish() {
await fetch("/api/revalidate", { method: "POST" });
router.refresh(); // forces the router cache to be bypassed for the current page
}
Summary
Reducing |
Beta Was this translation helpful? Give feedback.
-
|
A few things stand out here. Since you're already using: cache: "force-cache"
next: { tags: [...] }
revalidateTag(...)and the underlying data eventually becomes consistent, this doesn't sound like a simple tag invalidation failure. My first suspicion would be that you're dealing with multiple cache layers, not a single stale fetch. In App Router, a page can be affected by:
It's possible that A few questions that may help narrow it down:
One thing I'd try as a diagnostic step is temporarily adding: export const dynamic = "force-dynamic";to one of the affected routes. I wouldn't keep that in production, but if the issue immediately disappears, you've confirmed that a route-level cache is involved rather than the tag revalidation itself. Another thing worth checking is whether the list page and the post page are actually sharing the same source of truth. I've seen cases where: revalidateTag("posts")invalidates the list query, but the individual post page is populated through a different fetch, cache wrapper, CMS SDK cache, or The fact that:
makes me think Router Cache or Full Route Cache is the more likely culprit than I'd be interested to see:
That would help determine which cache layer is actually serving the outdated data. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Version Next JS: 15.5.2
Using App Router
Since we're using Next.js 15+, not all fetch requests are cached by default. Because of that, we explicitly added caching options:
For the posts list:
For a single post:
We also use a revalidation API endpoint where we trigger the following after a post is published, edited, or deleted:
The issue is that when a post is updated, the data is revalidated, but when navigating through our site—switching between pages such as the news feed (static), post page (dynamic), and home page (static)—we see inconsistent data.
On some pages, the post title is updated; on others, it still shows the old version. Sometimes the title on the single post page is outdated while the lists are already updated.
If we keep navigating between links, after about ~15 minutes, everything eventually syncs and shows fresh data. Additionally, if we manually refresh a page twice, only then does it display the updated content.
We're trying to decrease staleTime in the Next.js config from 5 minutes to 1 minute for static pages, but it hasn't helped.
Maybe someone has experienced this issue and successfully fixed it. Any suggestions or insights would be greatly appreciated.
Thank you!
Beta Was this translation helpful? Give feedback.
All reactions