SSR + Caching Strategy in Next.js: When to Use What
A practical breakdown of SSG, SSR, ISR, and PPR — when each rendering mode earns its place, and how to design a caching strategy that scales without surprising you at 3am.
SSR + Caching Strategy in Next.js
Most developers reach for SSR by default. It feels safe — fresh data, always. But SSR has a cost: every request is a round trip to your database, and under load, that adds up fast.
The Rendering Spectrum
Static (SSG) — built once at deploy time. Best for marketing pages, blog posts, docs. Zero server cost at runtime. The catch: stale until redeployment. ISR (Incremental Static Regeneration) — static with a TTL. Pages serve from cache and regenerate in the background. Perfect for product pages, dashboards with acceptable staleness. SSR — rendered per request. Use when data is user-specific or changes every second. Cart, auth-gated pages, real-time feeds. PPR (Partial Prerendering) — Next.js 14+ experimental. Static shell + streaming dynamic parts. This is the future for most apps.Practical Decision Tree
Is the content user-specific?
├── Yes → SSR
└── No → Can I tolerate N seconds of staleness?
├── No → SSR
└── Yes → ISR (revalidate: N)
└── Never changes → Static
Cache Layering
Don't rely on a single cache. Layer them:
1. CDN cache (Vercel Edge / Cloudflare) — serves most requests
2. In-memory cache (Redis) — DB query results, API responses
3. React cache() — deduplicates within a single render
What Breaks Your Cache
Personalization headers, auth cookies, and dynamic query params all bust CDN caching. If your ISR page sets a cookie, it won't cache at the edge. Keep dynamic logic out of statically cacheable routes.
The Right Mental Model
Think of rendering as a spectrum, not a binary choice. Most production apps use all modes simultaneously — static for the shell, ISR for product data, SSR for the cart, client rendering for real-time updates.