Next.js 16 has been released, focusing on developer feedback regarding caching behaviors in the App Router. The release changes the default caching settings, making the framework easier to reason about.
It resolves one of the most common complaints about the App Router.
Dynamic by Default
In previous versions, Next.js would aggressively cache data fetches and pages by default. While this improved static performance, it often led to users seeing stale data.
Next.js 16 reverses this behavior. Routes that use dynamic inputs are now dynamic by default.
If you want a page to be statically generated, you must explicitly opt-in using configuration options.
| Feature / Behavior | Next.js 15 (Default) | Next.js 16 (Default) |
|---|---|---|
Caching on fetch() | Cached (force-cache) | Uncached (no-store) |
| Route Caching | Statically Cached | Dynamic |
| Client Router Cache | 30 seconds (reused) | 0 seconds (always refetch) |
Simplified Fetch Caching
The caching behavior of the fetch API has also been streamlined. By default, fetches will no longer be cached unless you specify a revalidation interval.
This aligns Next.js closer to the standard Web Fetch API specification.
It reduces the need to constantly use revalidatePath or revalidateTag to force page updates.
Here is how you define a static route with explicit caching in Next.js 16:
// app/tools/page.tsx
// Explicitly declare static route parameters
export const dynamic = "force-static";
export const revalidate = 3600; // Cache for 1 hour
export default async function ToolsIndex() {
// fetch in force-static route must opt-in to cache to compile statically
const res = await fetch("https://api.example.com/tools", {
cache: "force-cache"
});
const tools = await res.json();
return (
<div>
{/* render tools */}
</div>
);
}
Improved Client Navigation Caching
The client-side router cache has been adjusted. Navigations will now check the server for fresh content more frequently.
This prevents the browser from displaying outdated pages when users click the back button.
It provides a smoother, more reliable user experience for web applications.
Upgrading an Existing App
If you're moving an App Router project from Next.js 15 to 16, the flipped defaults mean pages that relied on implicit caching will suddenly start hitting your backend on every request. Before upgrading, grep your codebase for fetch() calls inside Server Components and check whether any of them assumed the old force-cache default. Each one needs an explicit cache: "force-cache" or a revalidate value if you still want it cached.
The same applies to whole routes. Any route you know should stay static, marketing pages, blog posts, documentation, needs an explicit export const dynamic = "force-static" now. Routes that were accidentally static before (and serving stale data to users) will just work correctly without any code change, which is usually the bigger win: it's the silent bug fix, not the opt-in static routes, that most teams notice first after upgrading.
Tagged with
Written by
DebuggerMe TeamThe DebuggerMe team builds developer tools, writes technical content, and helps teams ship better software.
Related Articles
All articles →React Server Components in Depth: What They Are and When to Use Them
React Server Components fundamentally change how we think about rendering. This guide breaks down how they work, how they differ from Client Components, and the patterns that will make your Next.js apps faster.
Getting Started with Next.js 16: A Complete Guide
Everything you need to know to build fast, modern web applications with Next.js 16 App Router, Server Components, and TypeScript. From project setup to production deployment.
Turbopack Is Officially Production Ready
Turbopack has achieved production parity in Next.js, bringing massive build speed-ups and replacing Webpack.