WebAssembly Outside the Browser: What Ships in 2026

Source code displayed on a computer screen

WebAssembly stopped being a browser technology some time ago, and the interesting deployments are not the ones marketed loudly. They are the boring ones: a checkout discount rule at Shopify, a user-defined function inside a database, a CDN edge function, a Kubernetes pod that happens to be 200 kB instead of 200 MB. The unifying property is not speed. It is that you can run somebody else’s code in your process without trusting it.

The standards caught up in June 2026, when WASI 0.3 shipped with native async. That release is the first time the server-side story feels finished rather than promising.

WASI, and what 0.3 changed

WASI, the WebAssembly System Interface, is a set of standards-track API specifications for code compiled to the W3C WebAssembly standard. It is developed by the WASI Subgroup of the W3C WebAssembly Community Group, with documentation and tooling hosted by the Bytecode Alliance. Three milestones matter: 0.1 (Preview 1), the snapshot most existing toolchains still target; 0.2, which the Component Model documentation records as launching on 25 January 2024 with a stable set of WIT definitions; and 0.3.

WASI 0.3.0 was released on 11 June 2026. It moves async into the Component Model itself rather than layering it on top. stream<T> and future<T> become owned handles that transfer across component boundaries, the host runs one event loop instead of each component running its own, and the model is completion-based in the manner of Linux io_uring and Windows IOCP. The wasi:io package was removed outright, its functionality absorbed into native primitives. wasi:http/service replaces the old proxy world for HTTP servers and a new wasi:http/middleware world covers request-path middleware. Seven socket interfaces were consolidated into two.

“This is a stable release, which means programs you compile for it today are guaranteed to keep working in the future.” — Bytecode Alliance, WASI 0.3 launch announcement

Implementation status as of September 2026 is narrower than the specification. Wasmtime 46 is the first release to implement the final 0.3.0 specification, jco covers the features for JavaScript, and guest toolchains for Rust, Go, JavaScript, Python and C are in development rather than finished. If you are shipping this quarter, you are probably still targeting 0.2.

The component model, briefly

The Component Model is the part that makes Wasm a plugin format rather than a compilation target. A core Wasm module can only exchange integers and floats and a shared block of linear memory, which means every host has to invent its own calling conventions. Components add an interface description language (WIT), typed interfaces, worlds that declare what a component imports and exports, and composition so components can be linked to each other rather than only to the host. A Rust component and a Python component can call each other with records, strings, lists and results, without agreeing on a memory layout.

Where it actually runs in production

Deployment What Wasm provides Documented constraint
Fastly Compute Per-request instance, multi-language serverless at the edge Per-service and per-execution resource limits; 128 MB minimum memory for billing
Shopify Functions Merchant-supplied logic inside checkout Instruction count, module size and input size limits, checkable via Shopify CLI
ClickHouse Wasm UDFs User code inside the query engine, via Wasmtime Experimental; wasm32 only; not available in ClickHouse Cloud
SingleStore Code Engine Sandboxed UDFs, UDAFs and TVFs 16 MB sandbox by default; no syscalls, files, sockets, processes or threads
SpinKube on Kubernetes Wasm workloads scheduled as pods via a containerd shim CNCF sandbox-stage project

Edge runtimes

Fastly’s documentation states plainly that “Compute runs WebAssembly (Wasm)” and that “when a Compute request is received by Fastly, an instance is created and the serverless function is run,” with per-request isolation and lightweight sandboxing. Instance-per-request is only affordable if instantiation is close to free, which is the entire argument for Wasm at the edge over containers.

Plugin sandboxes

Shopify Functions is the most instructive example, because the sandbox is the product. Shopify supports “any language that compiles to WebAssembly (Wasm), such as Rust, Zig, or TinyGo,” and its language guidance is blunt about the trade: languages that compile directly to Wasm “perform better than dynamic languages, such as JavaScript,” and Rust is recommended for public apps, complex computation, or functions processing many line items, specifically to avoid hitting instruction limits. That is a platform admitting its own resource ceiling and telling developers to design for it.

Database extensions

ClickHouse’s Wasm UDFs use Wasmtime as the runtime, described as “the default, and currently the only one” implementation. Modules are loaded by inserting their binary into a system.webassembly_modules table, and three ABIs are supported: ROW_DIRECT for primitive numerics, BUFFERED_V1 for complex serialised types, and ASSEMBLYSCRIPT. Code must compile freestanding, with no OS or standard library dependencies, and the feature must be switched on with allow_experimental_webassembly_udf. SingleStore’s Code Engine takes the same shape with a firmer boundary: its documentation says each function instance gets its own in-process sandbox with a 16 MB linear memory allocation by default, and that functions cannot make system calls, open files, open sockets, send network messages, or create processes or threads. If a function crashes or exhausts memory, the query fails. That is the honest bargain: you get to run arbitrary user code in the database, and the blast radius is one query.

The performance reality

Wasm is fast relative to interpreted code and slower than native. The most-cited measurement is Jangda, Powers, Berger and Guha’s “Not So Fast: Analyzing the Performance of WebAssembly vs. Native Code” from USENIX ATC 2019, which found that applications compiled to WebAssembly “run slower by an average of 45% (Firefox) to 55% (Chrome), with peak slowdowns of 2.08x (Firefox) and 2.5x (Chrome)” on SPEC CPU benchmarks. The authors attributed part of the gap to immature code generation and part to the platform itself.

Two caveats before that number gets quoted at you. It measured browser engines in 2019, and standalone runtimes have had years of compiler work since. And CPU-bound SPEC benchmarks are the least favourable workload for Wasm; the edge and plugin cases that dominate production are I/O-bound, where startup cost and isolation overhead matter far more than steady-state throughput. The correct summary is that Wasm costs you some single-thread performance and buys you instantiation speed measured in fractions of a millisecond, which is the trade a plugin host wants and a numerical simulation does not.

What is still missing

  • 32-bit addressing by default. The mainstream target is wasm32, so linear memory is capped at 4 GiB. ClickHouse’s documentation notes only “the default 32-bit WebAssembly target is supported (no wasm64 extension).” Large in-memory datasets are out.
  • Toolchain maturity varies wildly by language. Rust and C/C++ are well served. Go via TinyGo is a subset. Garbage-collected and dynamic languages either ship their runtime inside the module, inflating size and startup, or rely on newer host GC support.
  • 0.3 support is thin. A specification released in June 2026 with guest toolchains still in development means production code targets 0.2 for now.
  • Operational tooling. Debuggers, profilers and observability for Wasm guests remain behind what any native or container workload gets for free.
  • Orchestration is early. SpinKube, the main path for running Wasm workloads as Kubernetes pods through a containerd shim and an operator, is a CNCF sandbox project, the foundation’s earliest maturity tier.

Pick the problem, not the technology

The test for whether server-side Wasm belongs in your stack is a question about trust boundaries, not performance. If you need to execute code written by customers, partners or a marketplace, inside your process, with a hard memory ceiling and no ambient access to the filesystem or network, Wasm is the only mature option that is not a container or a separate machine. If you are looking for a faster way to run your own trusted code, you will get more from a profiler than from a recompile. Start with a 0.2-targeted component and a small WIT interface, keep the host API surface deliberately narrow, and revisit 0.3 when your language’s toolchain lands it.

Sources

Post Comment