The Problem
Most Next.js apps ship slower than they should. Before v15, automatic caching was unpredictable — fetches were cached by default, invalidation was unclear, and client-side waterfalls crept in as apps grew. Teams spent days debugging stale data instead of shipping features.
The Solution
Next.js 15 hands control back to you. Explicit cache directives, Server Components that fetch their own data at the edge, and Partial Prerendering mean you can hit sub-200ms TTFB without fighting the framework.
The New Caching Model
Next.js 15 fundamentally rethinks caching. Gone are the days of aggressive automatic caching — now you opt in explicitly, giving you predictable, understandable behavior.
const data = await fetch('/api/posts', {
cache: 'force-cache',
next: { revalidate: 3600 }
});
Server Components First
Moving data fetching to the server eliminates client-side waterfalls. Each Server Component fetches its own data in parallel, reducing total load time dramatically.

Partial Prerendering
PPR lets you mix static shells with dynamic islands on the same page — the shell is served from the CDN in milliseconds while dynamic content streams in behind it.
Ship the shell, stream the rest." — The PPR mantra.
How to Migrate Your App
Audit your fetch calls
Run a global search for `fetch(` in your codebase. Add explicit `cache: 'force-cache'` or `cache: 'no-store'` to every call — no more implicit behavior.
Move data to Server Components
Identify every `useEffect` that fetches data and convert it to an async Server Component. Co-locate the fetch with the UI that needs it.
Enable Partial Prerendering
Add `experimental: { ppr: true }` to `next.config.ts` and wrap dynamic islands in `<Suspense>`. Your static shell ships from CDN instantly.
Measure with Lighthouse CI
Add Lighthouse CI to your GitHub Actions pipeline. Set performance budget gates to catch regressions before they reach production.
- Use Server Components for all data fetching
- Reserve Client Components for interactivity only
- Enable `experimental.ppr` in next.config.ts
- Profile with Chrome DevTools → Performance panel
- Set correct Cache-Control headers on the edge
Key Takeaways
- Next.js 15 uses opt-in caching — every fetch call needs an explicit cache directive
- Server Components eliminate client-side data waterfalls by moving fetches to the server
- PPR lets you mix static CDN-served shells with dynamic streaming content on one route
- Lighthouse CI in your pipeline catches performance regressions before users see them
- Profile with Chrome DevTools' Performance panel to find the biggest bottlenecks first
Frequently Asked Questions
PPR is marked experimental but stable enough for production with careful testing. Next.js 15.1+ has made it significantly more robust — many teams use it in production today.