Next.js 15 in production: what actually matters
Amir Hassan · 14 May 2026 · 2 min read

Every Next.js release arrives with a wave of breathless posts, and most of the advice in them never survives contact with a production incident. After shipping several Next.js 15 applications for clients this year, we have a clearer picture of what genuinely matters — and what is safe to ignore.
Start with the rendering decision
The most expensive mistakes we see in codebases we inherit are rendering-model mistakes. Pages that should be static are dynamic because someone read a cookie in a layout. Dashboards that should stream are blocked behind one slow fetch. Next.js 15 makes the boundaries more explicit — fetch requests are no longer cached by default — and that explicitness is a gift: it forces you to say what you mean.
Our rule on client work is simple. Marketing and content pages are static and revalidated on publish. Anything behind auth renders dynamically, with streaming for the slow parts. Deciding this per route, before writing code, eliminates the class of bug where a pricing change takes a day to appear because nobody knows what cached it.
Cache with intent, not by accident
The old default-caching behaviour produced fast demos and confused teams. The new explicit model means every cache is one someone chose. Use revalidateTag for content that changes on publish, short time-based revalidation for data that merely needs to be fresh-ish, and no cache at all for anything personal. Write the choice down next to the fetch. Future you is the audience.
Ship less JavaScript
Server Components are no longer novel, but teams still underuse them. The pattern that pays: keep pages as Server Components, push interactivity into small client leaves, and load anything heavy — editors, charts, 3D — dynamically when it enters the viewport. On a recent e-commerce build this took the product page bundle from 410KB to 160KB, and Largest Contentful Paint under a second on 4G.
Audit your client components: most exist for one onClick handler.
Dynamic-import anything over ~50KB that is not above the fold.
Measure on a mid-range Android phone, not your MacBook.
What we skip
Partial Prerendering remains experimental, and we do not ship experiments on client infrastructure. Turbopack for dev, yes — the speedup is real. Rewriting stable middleware to chase minor API refinements, no. Boring choices age well.
The meta-lesson from a year of Next.js 15: the framework rewards teams that make deliberate decisions and punishes teams that rely on defaults they have not read. That has always been true of production software. The tooling is just more honest about it now.
Share
Amir Hassan
Part of the team at The DevHub International.