Server-Side Rendering (SSR) vs Static Site Generation (SSG) vs ISR in 2026
When to use SSG, SSR, ISR, and Partial Prerendering in Next.js. Compare TTFB, edge cache hit rates, server infrastructure costs, and SEO implications.
Selecting a web rendering architecture dictates Time to First Byte (TTFB), search engine crawl budgets, and monthly serverless infrastructure bills. Serving static HTML from an edge content delivery network (CDN) delivers response times under 30 milliseconds. Executing server-side rendering on every HTTP transaction increases origin compute latency to 400 milliseconds or more. Next.js 15 restructures these paradigms into component-level rendering choices through Partial Prerendering (PPR) and granular caching controls.
Next.js Rendering Strategy Matrix: SSG vs SSR vs ISR
Answer 3 architecture questions to determine the optimal rendering mode for maximum speed and minimum server cost.
Generate static pages at build time or on first demand, then automatically revalidate in the background.
// app/catalog/[id]/page.tsx
export const revalidate = 3600; // Background rebuild every 60 mins
export async function generateStaticParams() {
return await getTop100ProductIds();
}What Are the Architectural Differences Between SSG, SSR, and ISR?#
Modern web engineering relies on three distinct strategies for generating HTML and executing React Server Components. Each strategy balances data freshness against compute expenditure and edge distribution efficiency.
Static Site Generation (SSG) compiles React components into static HTML files and JSON payloads during the production build step. Build workers store these immutable artifacts in object storage buckets (such as AWS S3 or Cloudflare R2). When a visitor requests a URL, the edge CDN serves the pre-rendered HTML without executing backend server code. SSG delivers maximum reliability and immune protection against database outages because client requests never reach origin compute instances.
Server-Side Rendering (SSR) executes React component logic on every incoming HTTP request. The Node.js or edge worker opens connections to external databases, queries data, evaluates request cookies or headers, compiles the component tree to HTML, and streams the response to the browser. SSR guarantees up-to-the-second content freshness but introduces origin latency bottlenecks, elevated cloud compute bills, and vulnerability to database connection pool exhaustion during traffic surges.
Incremental Static Regeneration (ISR) combines the edge caching speed of SSG with background asynchronous data updating via RFC 5861 stale-while-revalidate semantics. Next.js serves pre-rendered static HTML from the CDN edge while tracking asset validity windows. When a request arrives after the revalidation window expires, the edge cache serves the cached page to the visitor and triggers an asynchronous background worker thread. The worker queries updated data, regenerates the page HTML, and updates the edge cache for subsequent visitors without blocking user requests.
| Rendering Strategy | Edge TTFB (p50 / p95) | Edge Cache Hit Rate | Database Concurrency Pressure | Serverless Compute Invocations | Build Duration Overhead | Primary Target Workload |
|---|---|---|---|---|---|---|
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| Static Site Generation (SSG) | 15 ms / 35 ms | 99.2% | Zero (Build time only) | Zero per visitor | High (Grows with page count) | Documentation, marketing pages, blogs |
| Incremental Static Regeneration (ISR) | 20 ms / 45 ms | 96.8% | Low (Throttled by interval) | Low (Only on stale triggers) | Low (Builds top pages on demand) | Product catalogs, news portals, directory listings |
| Server-Side Rendering (SSR) | 280 ms / 850 ms | 0% (Uncached dynamic) | High (1 query per user request) | 1 invocation per visitor | Minimal (Code compile only) | Real-time dashboards, checkout flows, user portals |
| Partial Prerendering (PPR) | 25 ms / 50 ms | 98.5% (Shell hit) | Moderate (Isolated to dynamic slots) | Targeted to dynamic holes | Moderate (Static shell compile) | E-commerce detail pages, personalized landing hubs |
When Does Static Site Generation Deliver Superior SEO and Performance Results?#
Search engine crawlers allocate crawl budgets based on host responsiveness and server response times. Googlebot measures origin Time to First Byte across crawl sessions. When origin servers exhibit TTFB measurements above 600 milliseconds, Google crawler algorithms throttle request frequency, delaying the indexation of newly published catalog URLs.
Static Site Generation maintains flat TTFB metrics of 15 to 35 milliseconds globally. Serving static HTML from edge CDN points of presence allows search engine crawlers to parse thousands of URLs per minute without encountering rate limits or HTTP 504 gateway timeouts.
High-concurrency traffic surges demonstrate another distinct advantage of SSG. Flash traffic events (such as marketing announcements or influencer product promotions) overwhelm origin databases when using dynamic SSR. A sudden surge of 25,000 concurrent visitors generates 25,000 parallel SQL transactions, exhausting PostgreSQL or MySQL connection pools (max_connections). SSG absorbs millions of requests directly at the CDN edge cache, maintaining sub-30-millisecond response times while the origin database remains idle.
In Next.js 15, developers configure static pre-rendering for dynamic route segments using generateStaticParams:
// app/blog/[slug]/page.tsx
import { Metadata } from 'next';
import { notFound } from 'next/navigation';interface PageProps { params: Promise<{ slug: string }>; }
// Generate static routes at build time export async function generateStaticParams() { const posts = await prisma.post.findMany({ where: { published: true }, select: { slug: true }, take: 500, // Pre-render top 500 articles });
return posts.map((post) => ({ slug: post.slug, })); }
// Immutable static metadata generation
export async function generateMetadata({ params }: PageProps): Promise
if (!post) return { title: 'Not Found' };
return {
title: ${post.title} | ProNext Engineering,
description: post.excerpt,
};
}
export default async function BlogPostPage({ params }: PageProps) { const { slug } = await params; const post = await prisma.post.findUnique({ where: { slug }, });
if (!post) { notFound(); }
return (
{post.title}
By omitting request-time APIs (such as cookies(), headers(), or un-cached searchParams), Next.js emits immutable HTML files during next build, storing assets directly on edge networks.
How Does Incremental Static Regeneration Balance Real-Time Data with Edge Caching?#
E-commerce catalogs and enterprise directories cannot pre-render hundreds of thousands of pages at build time. Generating 100,000 static pages inside a CI/CD pipeline extends deployment durations to multiple hours, delaying software release cycles.
Incremental Static Regeneration resolves this build constraint through lazy compilation and background edge cache refreshing. Developers choose between time-based revalidation and event-driven on-demand tag revalidation.
Time-based revalidation defines a minimum cache lifespan in seconds:
// Revalidate page cache every 60 seconds
export const revalidate = 60;While functional, time-based revalidation introduces two operational limitations. First, if a product price updates in your enterprise resource planning (ERP) system, customers might view stale prices for up to 60 seconds. Second, if traffic ceases, background revalidation workers execute redundant compute cycles regenerating unchanged pages.
Event-driven on-demand cache revalidation solves both problems. Engineers tag data fetches with distinct identifiers. When a database update occurs, an API webhook purges matching cache tags across edge nodes within 200 milliseconds.
// app/products/[id]/page.tsxinterface ProductPageProps { params: Promise<{ id: string }>; }
export default async function ProductPage({ params }: ProductPageProps) { const { id } = await params;
// Tagged fetch cache definition
const res = await fetch(https://api.pronext.in/v1/products/${id}, {
next: { tags: [product-${id}, 'products'] },
});
if (!res.ok) notFound(); const product = await res.json();
return (
INR {product.priceINR.toLocaleString('en-IN')}
{product.name}
When an inventory manager updates stock in the database, the backend triggers an automated webhook hitting a secure Next.js API route:
// app/api/revalidate/route.ts
import { NextRequest, NextResponse } from 'next/server';export async function POST(request: NextRequest) { const authHeader = request.headers.get('x-revalidation-token'); if (authHeader !== process.env.REVALIDATION_SECRET_TOKEN) { return NextResponse.json({ message: 'Unauthorized execution' }, { status: 401 }); }
const { tag } = await request.json(); if (!tag) { return NextResponse.json({ message: 'Missing cache tag identifier' }, { status: 400 }); }
// Purges cached static asset across all global edge locations revalidateTag(tag);
return NextResponse.json({ revalidated: true, tag, timestamp: new Date().toISOString(), }); } ```
This event-driven workflow guarantees immediate content consistency while serving 98 percent of visitor traffic from edge memory.
What Is Partial Prerendering and How Does Next.js 15 Combine Static and Dynamic Trees?#
Traditional rendering architectures enforce an all-or-nothing constraint per URL. If a page requires personal user information (such as a shopping cart badge or user greeting), engineers must mark the entire route as dynamic SSR. Marking the route as SSR sacrifices sub-30-millisecond edge delivery, forcing every user to wait for database queries to resolve before receiving the initial HTML byte.
Partial Prerendering (PPR) in Next.js 15 eliminates this compromise by combining a pre-rendered static HTML shell with concurrent dynamic streaming holes over a single HTTP connection.
The compilation engine renders all static layout components (navigation bars, headers, typography, static product specifications, and footers) into an immutable static shell at build time. The framework positions React boundaries around dynamic components that require runtime data (such as user session cookies or live inventory checks).
// next.config.js
const nextConfig = {
experimental: {
ppr: 'incremental',
},module.exports = nextConfig; ```
In the page component, developers mark routes for experimental PPR:
// app/shop/[sku]/page.tsx
import { Suspense } from 'react';
import StaticProductOverview from '@/components/StaticProductOverview';
import DynamicUserCartBar from '@/components/DynamicUserCartBar';
import DynamicInventoryTicker from '@/components/DynamicInventoryTicker';export const experimental_ppr = true;
interface ShopPageProps { params: Promise<{ sku: string }>; }
export default async function ShopPage({ params }: ShopPageProps) { const { sku } = await params;
return (
{/ Static product content served directly from edge cache /}
{/ Dynamic inventory availability streamed without blocking shell /}
When a visitor requests the route, the CDN edge serves the static layout shell within 25 milliseconds. The user views navigation, imagery, and typography without delay. Concurrently, the edge worker executes the dynamic components and streams HTML fragments over the open HTTP connection, hydrating dynamic slots without layout shifts.
What Are the Real Hosting Cost Differences Between SSR and SSG at Scale?#
Choosing between dynamic server rendering and static edge delivery directly impacts monthly cloud infrastructure invoices. Evaluating an enterprise web application serving 10,000,000 monthly page views reveals substantial operational cost variances.
Under a pure SSR model, 10,000,000 page views require 10,000,000 compute function invocations. Assuming an average serverless execution time of 250 milliseconds with 1,024 MB memory allocation, the application consumes 2,500,000 GB-seconds of compute monthly. Furthermore, 10,000,000 dynamic queries necessitate high-throughput database connection pooling layers (such as AWS RDS Proxy) and provisioned IOPS storage to withstand peak connection loads.
Under an SSG and ISR model, the edge CDN serves 9,800,000 requests from memory cache hits. Only 200,000 requests trigger background regeneration workers or dynamic streaming endpoints.
| Expense Category | Monolithic Node.js (AWS ECS / Fargate) | Serverless Dynamic SSR (AWS Lambda / Vercel Pro) | Modern Headless SSG / ISR (CDN Edge + S3) |
|---|---|---|---|
| :--- | :--- | :--- | :--- |
| Compute Runtime Invocations | Fixed 4x 8GB Container Tasks ($280 / mo) | 10M Lambda Invocations ($142 / mo) | ~200k ISR Worker Calls ($2.80 / mo) |
| Edge Bandwidth (10M Hits @ 120KB) | 1.2 TB Data Transfer Out ($108 / mo) | 1.2 TB Edge Delivery ($108 / mo) | 1.2 TB CloudFront Transfer ($102 / mo) |
| Database Connection Pooling | 2x PgBouncer Instances ($65 / mo) | AWS RDS Proxy Active Pool ($48 / mo) | Zero pooling required for static ($0 / mo) |
| Database Provisioned IOPS | 3,000 Provisioned IOPS ($180 / mo) | 3,000 Provisioned IOPS ($180 / mo) | Baseline GP3 Storage ($24 / mo) |
| Total Monthly Cloud Expense | $633.00 / month | $478.00 / month | $128.80 / month |
Static Site Generation and Incremental Static Regeneration reduce direct cloud infrastructure expenses by 73 to 79 percent compared to full server-side rendering while delivering superior global Core Web Vitals metrics.
Frequently Asked Questions About Next.js Rendering Strategies#
Does Server-Side Rendering produce higher search engine rankings than Static Site Generation?
Server-Side Rendering does not provide an inherent SEO ranking advantage over Static Site Generation. Search engine crawlers (including Googlebot) evaluate the final delivered HTML document and Core Web Vitals performance. Static Site Generation delivers lower Time to First Byte (under 35ms) compared to SSR (280ms to 850ms), giving SSG an operational speed advantage in search ranking algorithms.
How does Next.js 15 detect whether a route requires dynamic server execution?
Next.js 15 inspects page components for dynamic functions and un-cached data sources during next build. If a component accesses cookies(), headers(), searchParams, or issues a fetch request with cache: 'no-store', the compiler marks that route for dynamic server-side execution. If a page avoids dynamic runtime APIs and resolves all data at build time, Next.js defaults to static generation.
What happens if an ISR background revalidation fails due to an upstream database outage?
If an upstream database fails during background revalidation, Next.js catches the build error and logs the event to your monitoring system. The edge CDN retains and serves the existing stale static version of the page, ensuring end users never view an HTTP 500 error page during origin outages.
Can an application combine SSG, ISR, and dynamic SSR inside a single Next.js project?
A single Next.js project can deploy all three rendering models concurrently across different route segments. Developers assign Static Site Generation to marketing pages and legal terms, Incremental Static Regeneration to product catalogs and blog listings, and Server-Side Rendering to private user dashboards and checkout flows.
Benchmarking Your Production Rendering Pipeline#
Choosing the correct rendering architecture dictates your application speed, infrastructure margins, and search discoverability. Verifying your rendering performance under realistic mobile network conditions uncovers latency bottlenecks before they affect user conversions.
Benchmark your site Time to First Byte and rendering distribution using /tools/speed-auditor, or explore our modern architecture modernization contracts at /website-packages to upgrade legacy web applications to high-speed Next.js 15 edge platforms.
Turn This Architecture Into Your Next High-Converting Website
Get custom Next.js engineering, sub-second performance, mobile lead automation, and transparent fixed pricing starting at ₹7,999. Shipped in 3 to 5 days.
Need Expert Guidance?
Replies within 2 minutes
Have a question about implementing this in your business? Chat directly with our senior architect.
Related Insights & Guides
Explore more strategic engineering articles
Reducing JavaScript Bundle Size: Tree Shaking, Dynamic Imports, and Code Splitting
Excessive JavaScript bundles block the browser main thread, inflate Interaction to Next Paint (INP), and degrade mobile conversion rates. Learn how to inspect bundle chunks with @next/bundle-analyzer, eliminate dead code with ES module tree-shaking, replace bloated npm packages, and split route payloads using next/dynamic.
Database Indexing & Query Optimization for High-Traffic Web Apps
Slow database queries saturate server CPU and trigger connection pool exhaustion under peak traffic. Learn how to diagnose sequential scans with EXPLAIN ANALYZE BUFFERS, construct multi-column composite B-tree indexes, and deploy PgBouncer connection pooling to maintain sub-5ms database latencies.
The Complete Guide to Cloud CDN Architecture: CloudFront vs Cloudflare vs Fastly
Engineering benchmark of top global CDNs. Compare TLS termination speeds, edge worker latency, cache invalidation protocols, and DDoS protection.