What happened
We assumed that once a Server Component had rendered, its output would be reused when the user navigated away and back, as if it were cached. After a client-side link click, though, one page felt slow, and the server logs showed its data fetch running again on every visit.
We spent time hunting for a client-side bug when the cause was on the server.
Why it happens
A Server Component's output is not a cache by itself. On a soft navigation, the client asks the server for the RSC payload of the new route segments, and the server renders them again. Layouts shared between the old and new route are not re-rendered, but the page segment is.
What can be reused depends on the version and settings. In Next.js 14, the client Router Cache keeps visited dynamic pages for 30 seconds, and the fetch() Data Cache is on by default. Next.js 15 changed those defaults: fetch requests are not cached by default, and page segments are not reused from the Router Cache unless you configure staleTimes. So it is safest not to assume either behavior.
What we do now
Decide explicitly for each fetch. For data that changes rarely, cache it with a tag and call revalidateTag when it changes. Keep per-user data dynamic. When several components in the same render read the same data, wrap the read in React cache() so it is only fetched once.
When testing, click through links rather than only doing a hard refresh, because the two take different paths through the caches.
const res = await fetch('https://api.example.com/products', {
cache: 'force-cache',
next: { tags: ['products'] },
})
const products = await res.json()Quick checklist
- 1Open the slow page and log what each Server Component fetches.
- 2Check the Next.js version, since the defaults differ between 14 and 15.
- 3Decide per fetch: always fresh, cached until a tag is revalidated, or cached for a period.
- 4Use React cache() to avoid repeated reads within one render.
- 5Test by clicking links, not only by reloading.
Rule of thumb
Never assume a Server Component's output is cached; decide the caching of each fetch explicitly.