Static, Server-Rendered or Client-Side: Which Should Your Site Be?
Rendering strategy is settled by two facts you already know: how often the content changes, and how much of the page depends on who is asking for it. Everything else follows from those two.
On This Page

A team spends three weeks deciding whether to go static or server-render, then ships a site whose slowest page is slow for a reason neither approach would have fixed. This happens constantly. The rendering argument is genuinely interesting, which is exactly why it absorbs attention that belonged to the content model, the image pipeline and the third-party script somebody added in week two.
So here is the position this piece defends. Rendering strategy is a real decision with real consequences, and it is also a smaller decision than the debate suggests, because two ordinary facts about your site settle it in about ten minutes: how often the content changes, and how much of each page depends on who is asking for it. Ask those, and the third option usually eliminates itself.
What follows compares the three on the four things that actually differ: what the visitor waits for, how stale the content can get, what you have to run, and what a bad day looks like. Then a decision rule, and an honest look at the hybrids that most real sites end up as anyway.
What each strategy actually does
Strip the marketing away and the three approaches differ on one question: at what moment is the HTML for this page assembled. Everything downstream is a consequence of that answer.
Static: assembled at build time
Pages are generated once, when you deploy, and served as files. The request path contains no application code, no database and no template engine, because all of that ran earlier on a machine that no longer exists. This is why static sites are hard to make slow and hard to knock over. It is also why publishing requires a build: a file does not change because a database row did. A workspace such as Acrosite takes exactly that approach, generating the files, committing them and triggering the configured deployment, so editors get an ordinary interface and the site keeps its build-time output.
Server-rendered: assembled per request
The HTML is built when somebody asks for it. The server reads whatever it needs, renders the page, and sends it. Content is as fresh as the data behind it, and the page can differ per visitor without any client-side work. The cost is that you now operate something: a runtime, a data source it depends on, and a capacity story for the day traffic arrives unannounced.
Client-side: assembled in the browser
The server sends a thin shell and a bundle of JavaScript. The browser downloads it, runs it, requests data, and paints the page. This model is genuinely good at one thing, which is a long-lived application session where the first load is amortised across an hour of use. It is a poor default for content pages, because you have moved assembly onto the slowest and least predictable computer in the chain, and you have made the content conditional on a script executing.
First paint: what the visitor waits for
A static page and a server-rendered page both arrive as HTML the browser can start painting immediately. The difference between them at the network edge is measured in the time it takes to render, which on a healthy server is small. A client-rendered page has to complete an extra round of work before anything meaningful appears: download the bundle, parse it, execute it, then usually fetch data over a second connection. Each of those steps is fine in isolation. Stacked, on a mid-range phone on a congested network, they are the reason a site tests well and feels slow.
This is where rendering strategy earns most of its reputation, and also where it gets over-credited. Going static will not save a page carrying an unoptimised hero image, three font files and a tag that blocks rendering. We have written the longer version of that argument in why a site is fast in the lab and slow for real users, and the short version is that rendering decides the floor, while payload and third parties decide where you actually land.
Freshness: how stale is acceptable
Every strategy has a staleness window, including the ones that claim not to. Server rendering is fresh at the moment of the request and then usually sits behind a cache, which reintroduces staleness through the back door. Static output is stale from the end of the build until the next one. Client-side fetching is fresh per request, at the cost of the visitor waiting for it.
The useful question is not "how fresh can we be" but "how wrong is it allowed to be, and for how long". A stock level that is ten minutes out of date will eventually sell something you do not have. A pricing page that is ten minutes out of date is fine. A published article that is ten minutes out of date is not a problem anyone has ever had. Write that number down per content type before you choose anything, because it converts a preference into a constraint.
Static builds grow with page count, and the growth is not gentle. A site that rebuilds in ninety seconds at launch can take considerably longer once a few thousand pages exist, and the day it crosses the line where nobody wants to fix a typo is the day the strategy quietly stops working. Incremental and on-demand regeneration exist precisely for this, but they need to be part of the plan rather than an emergency response.
What you have to run, and what it costs
The operational difference is larger than the performance difference, and it is the one teams underestimate. Static output is a directory of files: any host will serve it, a content delivery network will cache all of it, and there is nothing to patch on the request path. Server rendering means a running process, which means deployments, memory limits, scaling rules and a dependency on whatever data store it reads from. Client-side rendering moves the compute to the visitor and the coordination cost to your API.
| Concern | Static | Server-rendered | Client-side |
|---|---|---|---|
| HTML assembled | At build time | Per request | In the browser |
| Time to first content | Fastest, from cache | Fast, depends on the server | Slowest, needs the bundle first |
| Freshness | As of the last build | As of the request, minus cache | As of the fetch |
| Per-visitor content | Needs a client-side layer | Native | Native |
| What you operate | A file host | A runtime plus its data source | An API the browser calls |
| Traffic spikes | Absorbed by the cache | A capacity decision | Shifts to the API |
| Cost driver | Build minutes and bandwidth | Compute time and instances | API calls and bundle size |
| Search visibility | Straightforward | Straightforward | Depends on rendering succeeding |
The last row deserves more weight than it usually gets, and so does the running cost of the middle column. A server-rendered site is a service, with everything that implies: on-call, upgrades, an incident when the database is slow. That is not an argument against it. It is an argument for counting it honestly, which is the same accounting exercise we set out in what it costs to maintain the thing you just built.
Failure modes: what a bad day looks like
Architectures are best compared on their worst behaviour, not their best. Each of these three fails in a characteristic way, and knowing the shape in advance is most of the value of choosing deliberately.
How static fails
Static fails at publish time rather than at request time, which is the kindest possible failure. A broken build means the old site stays up while somebody fixes it. Visitors see nothing wrong. The genuine failure mode is different: a build that takes so long, or breaks so often, that publishing becomes an event people avoid. Content then rots because updating it is annoying, and a slightly stale site is worse than a slightly slower one.
How server and client rendering fail
Server rendering fails at request time and in public. A slow query, an exhausted connection pool or an unhealthy instance turns into an error page for real people, and the failure often arrives with your busiest hour. Client rendering fails more quietly and more strangely: the shell loads, the bundle fails or a request times out, and the visitor gets a page that looks like a site with no content in it. Content that depends on a script executing is content that can disappear, which is why a client-heavy front end needs a serious answer for what the page shows when the data never arrives.
A decision rule you can apply this afternoon
Work through these in order, per content type rather than per site. Most teams stop at question three.
- Does this page differ per visitor? Not "could it one day", but does it, on launch day? If yes, you need server rendering or a client-side layer for the parts that differ. If no, static is on the table and stays there.
- How often does the content change? Daily or less often points at static. Continuously, or from a system you do not control, points at rendering per request.
- How wrong may it be, and for how long? Write the tolerance down as a duration. That number decides whether a build cadence is acceptable or whether you need regeneration.
- How many pages will exist in three years? Page count is what turns a comfortable build into an uncomfortable one, and the crossing point arrives without a warning.
- Who operates it at three in the morning? A runtime is a service somebody owns. If nobody owns services, choose the option that does not create one.
Choose the model where your worst hour is survivable, not the one where your demo is elegant. Sites get judged on the day something breaks.
Hybrids, honestly
Almost every serious site is already a hybrid, and modern frameworks have made mixing strategies a per-route decision rather than an architectural one. That is a real improvement. It is also how teams end up with four rendering modes and nobody able to say which pages use which.
- Static shell, dynamic island. The page is built once; the one element that must be live, such as availability or a cart count, fetches on the client. Cheap, and it keeps the failure contained to a small region.
- Regenerated static. Pages are static but rebuilt on a schedule or when the content system says so. This is the right default for large catalogues that change unpredictably but not constantly.
- Server-rendered with heavy caching. Effectively static for anonymous visitors and dynamic for signed-in ones. Powerful, and it makes the cache key the most important line of configuration you own.
- Static marketing, application behind a login. Two systems, one domain. The most common shape we see, and usually the correct one.
The rule we apply is that a hybrid needs a written policy, not a habit: which route uses which mode, and why. Without it you get a codebase where nobody can predict whether a change ships instantly or waits for a build. And when the dynamic parts start calling out to something else, the shape of that contract matters more than the rendering does, which is the subject of API design for people who will use it in two years.
Where we would start
For a marketing site, a publication, documentation, or anything a search engine and a stranger arrive at cold: static by default, with regeneration when the page count or the change frequency demands it. The reasons are unglamorous. It is the cheapest to host, the hardest to break, the least to patch, and it fails at publish time instead of in front of a customer. Most website builds we would recommend start here and only move when a specific requirement pushes them.
Server rendering earns its keep when pages genuinely differ per visitor, when inventory or pricing must be correct at the moment of the request, or when a store catalogue is too large and too volatile to rebuild. Client-side rendering earns its keep inside an application, after authentication, where the session is long and the first load is a one-off tax. Outside those cases it is usually a habit rather than a decision.
One concession worth stating plainly: if your team is already fluent in one model and shaky in the others, familiarity often beats theory. A well-run server-rendered site from people who understand caching will outperform a static build from a team learning the toolchain during a launch. That is the same trade as build or buy, where the correct answer depends on who has to live with it rather than on which option reads better on a slide.
And the step before any of this: decide what the site is actually for, because a brochure, a catalogue and a product need different answers and often get given the same one. Our parent company has written about that framing in what a company actually sells. More of our engineering writing sits in Technology insights, and if you want a read on a specific stack, describe what you are building.
Common questions.
What is the difference between static site generation and server-side rendering?
Static site generation builds the HTML once at deploy time and serves the resulting files to everybody. Server-side rendering builds the HTML separately for each request, so it can reflect current data and differ per visitor. Static is cheaper to host and harder to break, while server rendering keeps content current without a rebuild. The trade is freshness against operational simplicity.
Is client-side rendering bad for search engines?
It is riskier rather than automatically bad. Search engines can execute JavaScript, but rendering is a separate and slower stage than crawling, and anything that fails during it can leave the page looking empty. Content delivered as HTML is indexed on the first pass with no dependency on script execution, which removes a whole category of intermittent problems that are difficult to diagnose.
When should a site use incremental or on-demand regeneration?
Use it when the page count makes full rebuilds impractical but the content still changes less often than every request. Regeneration keeps the delivery characteristics of static files while letting individual pages refresh on a schedule or when the content system signals a change. Large catalogues, documentation sets and publications with thousands of entries are the usual candidates.
Does static rendering make a website fast on its own?
No. Static rendering removes server time from the request, which sets a good floor, but the visitor experience is mostly decided by payload. Oversized images, several font files, render-blocking scripts and third-party tags will make a static page slow on a mid-range phone. Rendering strategy decides the best case; the assets on the page decide the actual result.
Can one website mix rendering strategies?
Yes, and most substantial sites do. Modern frameworks let each route choose its own mode, so marketing pages can be static while an account area renders per request. The requirement is a written policy stating which routes use which mode and why. Without that, nobody can predict whether a given change ships immediately or waits for the next build.
What happens to a client-rendered page if the JavaScript fails?
The visitor sees the shell with no content, usually a blank region or a spinner that never resolves. Because the markup is assembled in the browser, a failed bundle, a blocked request or a slow API removes the page rather than degrading it. Any client-heavy front end needs a deliberate answer for that state, including a visible error and a route that still works.
Facing this in your
own business?
Tell us where you’re headed — we’ll map the shortest honest route.