Back to Blog
Guide9 min read2026-07-14

Static vs SSR vs SSG vs ISR: How to Actually Choose

What each rendering strategy really means, what it costs to host, and a decision framework that doesn't start with 'it depends'.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Rendering strategy debates generate a lot of heat because people argue about acronyms instead of the one question that matters: when is the HTML for a given page produced, and by what? Answer that, and everything else — hosting cost, data freshness, cold starts, SEO behavior — falls out mechanically.

Here's each strategy in those terms, the trade-offs that actually bite in production, and a decision process you can apply to a real app.

The four strategies, defined by when HTML is made

Client-side rendering (CSR): HTML made in the browser

The server sends a nearly empty HTML shell plus a JavaScript bundle; the browser fetches data and renders everything. A classic Vite + React SPA works this way.

  • HTML produced: at runtime, in the user's browser.
  • Server needed: no — it's static files. Any CDN or static host serves it.
  • Cost: users see a blank page or spinner until the bundle loads and the API responds. Search engines handle JS better than they used to, but crawl budget and social-link previews still suffer.

CSR gets dismissed too quickly these days. For an app behind a login — a dashboard, an admin panel, an internal tool — SEO is irrelevant and the user has already committed to waiting. A SPA is often the simplest correct choice there.

Static / SSG: HTML made at build time

Static site generation renders every page to HTML during the build. Astro, Hugo, Eleventy, Gatsby, VitePress, and Next.js with output: 'export' all do this. ("Static" and "SSG" get used interchangeably; strictly, static is the artifact — plain files — and SSG is the process that produces them from templates and data.)

  • HTML produced: once, at build time, on a build machine.
  • Server needed: no. The output is files; a CDN serves them.
  • Cost: content is frozen at build time. New blog post? Rebuild. Price change? Rebuild. And build time scales with page count — a 50,000-page site regenerating everything per deploy becomes a CI bottleneck.

The upsides are hard to overstate: near-zero hosting cost, excellent time-to-first-byte from CDN edges, no server to patch, no process to crash, essentially nothing to attack. For content that changes on human timescales — marketing sites, docs, blogs — SSG is the correct default in 2026, full stop.

SSR: HTML made per request

Server-side rendering runs your framework on a server that produces HTML for each request. Next.js (default server mode), Nuxt, SvelteKit with a Node adapter, Remix — all SSR frameworks.

  • HTML produced: at request time, on your server.
  • Server needed: yes — a long-running process (or serverless function) on every request path.
  • Cost: you now operate compute. Every page view costs CPU. Response time includes your data fetching, on every hit. Traffic spikes are your problem. And if the platform scales your app to zero when idle, the first visitor pays a cold start.

What you buy is *freshness and personalization*: the HTML can reflect this user, this second. Authenticated pages with server-rendered user data, search results, pricing that varies by region, inventory that changes by the minute — these genuinely need request-time rendering.

ISR: static pages that heal themselves

Incremental static regeneration — popularized by Next.js ([nextjs.org/docs — ISR](https://nextjs.org/docs/app/building-your-application/data-fetching/incremental-static-regeneration)) — serves prebuilt static pages but regenerates them in the background after a revalidation window, or on-demand when your CMS fires a webhook. Users get static-speed responses; content stays at most N seconds stale.

The catch people miss: ISR is not static hosting. Regeneration requires a server runtime and a shared cache — it's a platform feature, not a property of the files. Deploy an "ISR" app as plain exported files and you've silently got stale-forever SSG. If you rely on ISR, you're deploying a server (or a platform that emulates one), with everything that implies.

The trade-off table

CSRSSGSSRISR
HTML producedin browserat buildper requestat build + background refresh
Server requirednonoyesyes (runtime + cache)
Data freshnesslive (via API)build-timelivebounded staleness
TTFBfast shell, slow contentfastestdepends on your codefast
Hosting cost~zero~zerocontinuous computecompute, mostly idle
Personalizationyes (client-side)noyesno (per-page, not per-user)

How to choose: three questions

1. Does the page differ per user? If the HTML itself must vary by viewer, you need runtime rendering — SSR for public pages where SEO matters, CSR for logged-in app surfaces. If pages are the same for everyone, keep going.

2. How stale can it be? Changes on deploy anyway (docs, marketing)? SSG. Minutes of staleness acceptable (news, product listings)? ISR, if your platform supports it — or honestly, SSG with a rebuild webhook from your CMS, which is simpler and easier to reason about. Seconds matter (inventory, dashboards)? SSR or client-side fetching.

3. How many pages? Ten thousand mostly-cold pages make full SSG rebuilds slow; that's the actual problem ISR was invented for. A few hundred pages? Rebuilds take a minute; skip the complexity.

Note that this is a per-page decision, not a per-app decision. Modern frameworks mix modes: a Next.js app can statically generate the landing page, ISR the blog, and SSR the account pages. Astro is static by default and opts individual routes into server rendering ([docs.astro.build — on-demand rendering](https://docs.astro.build/en/guides/on-demand-rendering/)). Choose the cheapest strategy each page can get away with.

What this means for hosting

The strategy you pick determines what you deploy:

  • CSR and SSG output plain files. On PandaStack these deploy as static sites — connect the repo, the framework and build command are auto-detected (Astro, Gatsby, Eleventy, VitePress, Next.js export, plain HTML), and the output ships behind a custom domain with automatic SSL. The free tier includes 5 static sites and 100 GB of bandwidth a month, which covers a lot of blogs.
  • SSR and ISR need a running process. That means a container app: a Dockerfile or an auto-detected Node/Python/Go build, deployed as a server with live build and runtime logs. If it needs data, a managed Postgres/MySQL/MongoDB/Redis instance attaches with DATABASE_URL injected automatically.
  • One relevant detail for SSR on free tiers anywhere: platforms that scale idle apps to zero (PandaStack's free tier does this) will impose a cold start on the first request after a quiet period. Great economics for a side project; wrong plan for a latency-sensitive production API — that's what the paid tiers are for.

The pattern I recommend most often: static-generate everything public, run one small SSR/API container for the dynamic parts, and let a rebuild webhook handle content updates. It's boring, cheap, and fast — the three best qualities infrastructure can have.

If you want to test a strategy against reality, deploying both a static build and an SSR container takes a few minutes each on [pandastack.io](https://pandastack.io).

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Guide

Browse all Guide articles →

See also