Four acronyms, four trade-offs, four very different cost models, and a tendency in framework marketing to imply that one of them is universally better than the others. SSR is back, CSR is dead, ISR fixes everything, SSG is for blogs. None of those slogans survive contact with a real product, and most teams I have helped picked the wrong one because they followed the slogan instead of the data.
My stance: the right rendering strategy for a page falls out of two questions, asked in this order. How fresh does the data need to be? How personalized is the page? Once you answer those, the choice between SSG, ISR, SSR, and CSR is mostly forced. The acronyms are not competing philosophies; they are points on a freshness-and-personalization axis, and most apps need more than one of them in the same codebase.
Four acronyms, one decision
Every rendering strategy moves the work between three points: build time, request time, and browser time. SSG does it all at build. SSR does it at request. CSR does it in the browser. ISR does it at build with periodic refresh. The trade is between freshness, latency, and per-page cost.
SSG: render at build, serve forever
Static site generation runs the page once at build time and saves the resulting HTML. Every visitor gets the same bytes from a CDN. There is no per-request server work, no database query under load, no rendering bottleneck.
The cost profile is unbeatable for content that does not change between deploys: marketing pages, documentation, blog posts, terms of service, an about page. A page that ships from a CDN edge node in 30 ms with no origin call is faster than any other strategy can be.
The failure mode is staleness. If the content needs to update between deploys, SSG either forces you to redeploy on every change (fine if the build is fast and the changes are infrequent) or accept stale content until the next build. A 50,000-page e-commerce catalog regenerated nightly has 24-hour-stale prices, which is not acceptable for any e-commerce I have worked on.
The tell that SSG is right: the page is the same for every viewer and changes rarely. Marketing site, docs site, content with editorial review cycles measured in days not minutes. SSG wins these flat out.
ISR: render at build, refresh on demand
Incremental Static Regeneration is SSG with a sliding-update mechanism. The page is statically generated and cached, and after a configurable interval (or on a webhook from a CMS, or on a redeploy of a single path) the cache is invalidated and the next request triggers a regeneration in the background.
The sweet spot is content that changes occasionally but not on every request. Product pages on an e-commerce site where prices update a few times a day. A blog index where new posts appear hourly. A pricing page where the marketing team edits weekly. ISR gives you SSG's CDN-fast-as-possible read path with a refresh story that does not require a full deploy.
The model that finally clicked for me: ISR is a CDN-with-render-on-miss. The first request after a cache miss pays the rendering cost; subsequent requests in the next 60 seconds get the cached version. If your data does not need to be sub-second fresh, ISR's economics are extraordinary.
Where ISR breaks: pages that need to be different per user. The cache is a single shared cached HTML; if user A and user B should see different content, ISR cannot serve them both from the same cache key. You can shard by URL parameter, but at that point you are doing user-specific caching and the cache hit rate plummets.
SSR: render per request
Server-side rendering runs the component tree on every request, with whatever data the request needs (the user's session, locale-specific content, real-time data). The browser receives complete HTML; the server pays the cost of every page view.
SSR is the right choice when:
- Each user sees a different page (logged-in dashboard, personalized home).
- Data must be fresh on every request (live trading prices, sports scores).
- The page's content depends on the request (search results from a query string).
The cost is throughput. Every page view runs the render path on a server, which competes with every other render and every database query. A site doing 100 requests per second under SSR needs servers that can render 100 pages per second; under SSG the same load barely registers because it is just CDN bytes.
A pattern I keep advocating for: do not SSR pages that could be ISR. Logged-out marketing pages, public catalog pages, content pages, all should be SSG or ISR even if your framework defaults to SSR. The default is misleading because SSR works for everything; that does not mean SSR is the right answer for everything.
CSR: render in the browser
Client-side rendering ships an empty HTML shell with a JavaScript bundle that does the entire render in the browser. The server returns roughly the same bytes for every URL, and the browser fetches data and renders the UI on its own.
CSR is the right choice for:
- Highly interactive apps where the first paint does not need to be fast (internal tools, admin panels, design tools, dashboards behind a login wall).
- Apps where every screen is dynamic and personalized and SSR would cost too much per request.
- Apps where the server is genuinely just an API and there is no rendering layer.
The cost is the first paint. Until the bundle downloads and runs, the user sees nothing or a loading spinner. For logged-in apps where the user already loaded the bundle in a previous session and the bundle is cached, this is fine. For a public landing page, it is unacceptable.
The thing teams keep getting wrong with CSR: shipping it for content that should never have been client-rendered. A landing page that takes 2 seconds to first paint because the user has to download 400 KB of JavaScript first is the canonical CSR mistake. If the page is content, not interaction, do not CSR it.
The decision matrix
The matrix I run through for any new page:
| Question | If yes | If no |
|---|---|---|
| Is the content the same for every user? | continue | jump to SSR or CSR |
| Does the content change less than once per minute? | SSG or ISR | continue |
| Is the content highly personalized? | SSR | CSR |
| Is the page interactive enough to need the bundle anyway? | CSR is fine | SSR for first paint |
A blog post: same for everyone, changes rarely, SSG.
A product page on an e-commerce site: same for most users, prices update daily, ISR with 5-minute revalidate.
A logged-in dashboard: different per user, SSR (or CSR if the bundle is already cached).
A design tool: highly interactive, CSR with a server that exists only to serve data.
A homepage with personalized recommendations: most of the page is SSG, the recommendations slot is CSR or streaming SSR.
The modern frameworks let you mix these per route, and the right architecture for most products is a mix. The marketing pages are SSG. The product pages are ISR. The logged-in app is SSR or CSR. There is no single right answer for the whole app; there is a right answer for each page.
A failure mode worth naming: choosing for the wrong axis
The mistake I see most: teams that pick a rendering strategy because of TTFB benchmarks without checking whether their actual constraint is data freshness. They benchmark SSR against SSG on cold cache, see SSG winning by 200 ms, and migrate everything to SSG. Six months later they have a content management problem because every editorial change requires a full rebuild, and the performance win is invisible to users who would have been fine with ISR.
The inverse: teams that move from CSR to SSR for SEO reasons and discover their per-request server costs went up tenfold because every search-engine crawl now hits the database. The right answer was probably ISR for the public pages and CSR for the app behind the login.
Pick by the data freshness and personalization questions first. Performance falls out as a consequence; if it does not, you picked wrong on the first questions.
Two rendering rules and a warning
Rule one: build-time work is free at request time. If you can make a page SSG, you should. The user experience is faster, the cost model is cheaper, and the failure modes are simpler (a build either succeeded or failed, there is no "the request crashed mid-render").
Rule two: per-user content needs per-request rendering. Either SSR or CSR. The choice between them comes down to whether the first paint matters. If it does, SSR. If the user is already in the app, CSR is fine.
The warning: do not let the framework's default fool you into thinking the framework chose for you. Next.js's app router defaults to dynamic rendering when it sees a database call without revalidation; that is SSR by default, even for pages that should have been ISR. React Router defaults to CSR; that is fine for an SPA, wrong for a content site. Read what your framework picked for each route, and override it where the page's data shape does not match the default. The right strategy is the one that matches the data, not the one the framework happened to choose.
