Static, Server-Rendered, or Client-Rendered
21 Oct 2026The question isn’t “which is faster” — static wins that every time. The real question is how often your data changes, and whether stale content is acceptable between rebuilds.
The decision framework
flowchart TD
A["How often does the data change?"] --> B["Rarely / on deploy\n(docs, marketing, blog)"]
A --> C["Per-user or per-request\n(dashboards, carts, feeds)"]
A --> D["Frequently, same for everyone\n(prices, inventory, news)"]
B --> E["Static rendering"]
C --> F["Server rendering,\nor client rendering"]
D --> G["Static + ISR/on-demand\nrevalidation"]
Static rendering
Pages are built once, at deploy time, and served as plain files from a CDN. No server compute per request.
- Use for: marketing pages, docs, blog posts, anything where all visitors see the same content and it changes only when you redeploy.
- You get: the fastest possible TTFB, because there’s no rendering work at request time — just a file being served from the edge.
- You lose: freshness. If your data changes and you don’t rebuild, users see stale content until the next deploy.
Server-side rendering (SSR)
Each request runs your rendering code on a server, producing fresh HTML every time.
- Use for: pages that must reflect current, request-specific state — a logged-in dashboard, a cart total, personalized recommendations.
- You get: always-current data, no stale content.
- You lose: speed. Every request pays render time and, usually, a database round trip. This is the tradeoff teams forget: SSR isn’t “static but fresher,” it’s a live compute cost on every single page view.
Client-side rendering (CSR)
The server sends a near-empty HTML shell; the browser fetches data and renders in JavaScript.
- Use for: highly interactive, authenticated app views where SEO doesn’t matter and the user is already loaded into an app shell (post-login dashboards, internal tools).
- You get: cheap server cost — you’re mostly serving static JS bundles.
- You lose: first paint is slow (blank screen until JS loads and fetches), and SEO is poor unless you add rendering elsewhere. Don’t use CSR for anything you want indexed.
The middle ground: incremental static regeneration / on-demand revalidation
Static pages that rebuild automatically on a schedule or when triggered by a webhook, without a full site rebuild.
- Use for: content that changes periodically but not per-request — product prices updated hourly, a news homepage, inventory counts.
- You get: static-speed reads most of the time, with a bounded staleness window you control (say, revalidate every 60 seconds, or on a CMS webhook).
- The gotcha: if your revalidation trigger breaks (webhook fails silently, cron stops), pages go stale with no error — nothing tells you the page hasn’t rebuilt in three days. Monitor your last-rebuilt timestamp, don’t assume the trigger fired.
The rule that actually decides it
Ask “if this page were 10 minutes stale, would anyone notice or care?” If no — static. If “only for this specific logged-in user” — SSR or CSR depending on whether it needs to be crawlable. If “yes, money or inventory is wrong” — SSR, or static with aggressive revalidation and a visible “last updated” timestamp so staleness is honest instead of hidden.