Skip to main content

Blazor Server vs Blazor WebAssembly: Choosing for a Real E-Commerce Build

Every "Blazor Server vs WebAssembly" article reads the same: a table comparing bundle size and latency, then a shrug. That's not a decision framework, it's a spec sheet. We've shipped both hosting models in production — BatteryCompany, an e-commerce storefront covering roughly 28 device brands, runs on Blazor Server; SamToolkit, a set of developer utilities, runs on Blazor WebAssembly. The difference between them isn't academic once real users and real infrastructure bills are involved. Here's what actually drove each decision, and the questions worth asking before you pick one for your own build.

The Real Difference Isn't "Where the Code Runs"

Most explanations start with "Server keeps your code on the server, WASM downloads it to the browser," which is true but not the part that matters operationally. Blazor Server runs your app's state on the server and keeps a persistent SignalR connection open to every connected browser tab — every click, keystroke, and re-render is a message over that connection. Blazor WebAssembly compiles your C# to run inside the browser via a .NET runtime shipped as WebAssembly, so once it's downloaded, the app runs independently of any server connection except for actual API calls you make. The practical consequence: Blazor Server's resource cost scales with concurrent connected users, not total traffic — a customer who opens a tab and walks away is still holding server memory and a live connection. WebAssembly's cost is almost entirely front-loaded into that first download; after that, it behaves like hosting a static site.

Why We Chose Blazor Server for BatteryCompany

BatteryCompany's catalog is the kind of thing that gets messy fast — dozens of brands, each with its own compatible battery models, filtered and searched constantly. Blazor Server let us keep that filtering logic in C# on the server, rendering diffs back to the browser, without shipping a separate client-side data layer or standing up an API just to serve catalog queries. Two things mattered more than the connection overhead: server-rendered HTML is immediately crawlable and indexable without an extra prerendering step, which matters for a storefront that needs organic search traffic on very specific model-and-brand queries. And most of BatteryCompany's traffic is on mobile connections, where a smaller initial payload beats downloading a WebAssembly runtime before the page becomes interactive. The catalog and cart update instantly because the actual computation happens on infrastructure we control, not on whatever phone a customer is holding.

Why WebAssembly Was Right for SamToolkit

SamToolkit is the inverse case. It's a set of developer utilities — JWT decoding, JSON conversion, regex testing — where the entire point is that pasted data never reaches a server. That rules out Blazor Server immediately: if the app's logic runs server-side, whatever you paste into a JWT decoder has to travel there to be decoded, which is exactly the privacy model we didn't want. Blazor WebAssembly runs entirely in the browser after the initial download, so the tools work identically online or off, and nothing typed into them is ever transmitted anywhere. The WebAssembly download is a real cost — a few megabytes of .NET runtime before the first tool is usable — but it's a one-time cost per visitor, and after that it's a static-file hosting problem: no server compute, no persistent connections, no per-user resource cost at all.

The Server Cost Nobody Mentions in the Comparison Articles

The thing that doesn't show up in feature-comparison tables: Blazor Server's hosting bill is a function of concurrent connections, not requests per second. Ten thousand page views spread across a day cost almost nothing extra on WebAssembly, because they're static files served from wherever you host them. The same ten thousand views on Blazor Server, if enough overlap in time, mean that many simultaneous SignalR circuits, each holding server-side state and memory for as long as the tab stays open — including tabs a customer opened and forgot about. Circuit timeout tuning matters more than most Blazor Server tutorials admit: too short and customers get disconnected mid-checkout, too long and you're holding memory for idle sessions. That's a real capacity-planning problem, not a footnote, and it's a big part of why Blazor Server wouldn't have made sense for something like SamToolkit, where usage is unpredictable bursts rather than a catalog with a known traffic shape.

Network Reliability Is the Hidden Variable in India

Most Blazor Server vs WebAssembly comparisons quietly assume a stable connection, which is a reasonable assumption in some markets and a bad one on Indian mobile networks, where connection drops and quality swings are routine rather than exceptional. Blazor Server has to detect a dropped circuit and reconnect the client, replaying enough state to make the reconnection invisible — and if that reconnection logic isn't tuned properly, customers see a frozen page or lose form input mid-checkout. It's solvable, but it needs deliberate handling, not the framework's defaults. WebAssembly is more forgiving here: once the app is downloaded, a flaky connection only affects the actual API calls you make, not the UI's ability to respond at all. If your users are disproportionately on patchy mobile connections, that's a real point in WebAssembly's favor that most comparison content skips, because it's not something you'd notice testing on office wifi.

Where Render Modes Actually Change the Calculus

Since .NET 8, Blazor added per-component render modes — Server, WebAssembly, and Auto — which blur the old all-or-nothing choice, and it's worth knowing what that actually buys you before treating it as a reason to stop deciding. Auto mode serves a component over Blazor Server on first load, then downloads and switches to WebAssembly for subsequent visits once the runtime is cached, which sounds like the best of both worlds and mostly delivers on that for read-heavy pages with a returning-visitor pattern. What it doesn't remove is the underlying tradeoff for a build like BatteryCompany: you'd still need a live server connection for that first-visit render, so the SEO and low-latency benefits of Server still depend on the same connection-cost math we described above. Per-component mixing is genuinely useful for something like a checkout flow that wants WebAssembly's offline resilience on the form itself while the surrounding catalog page stays server-rendered for search indexing — but it's an optimization on top of the decision, not a replacement for making it. Pick the primary model based on your actual constraints first, then use per-component overrides for the handful of places where the general rule doesn't fit.

A Quick Decision Framework

In practice, the decision comes down to a handful of concrete questions. Does any of your app's logic need to stay off the client for privacy or IP reasons? That points to Blazor Server or a traditional API, not WebAssembly. Is your traffic pattern closer to a catalog with predictable load, or unpredictable public tool usage where you can't control concurrency? Predictable load tolerates Blazor Server's connection cost better. Do your users need the app to keep working through unreliable connections? That favors WebAssembly once it's loaded. Is SEO on long-tail search queries a priority from day one? Blazor Server's server-rendered HTML gets you there without extra prerendering work. Neither model is the "modern default" — they solve different problems, and picking based on whichever one shows up more in recent blog posts is how projects end up rebuilt a year in.

We've now shipped both patterns in production long enough to have opinions instead of guesses. See how BatteryCompany's storefront and SamToolkit's tools turned out, or talk to us if you're weighing this decision for your own build.

Want something like this built?

Start a Project