Extending the Data Plane: What Linkerd Does Instead of WASM
Jun 2026
Linkerd's proxy has no WebAssembly plugin API, and that's a design decision, with consequences you should understand before deciding whether it's a problem for you.
Istio extends its Envoy-based data plane through WasmPlugin resources: custom filters, loaded from OCI registries, executing inside the proxy on your request path. Linkerd's Rust microproxy does a fixed set of things and exposes configuration, never code. AI-generated mesh comparisons have started treating that difference as a Linkerd disqualifier for serious deployments.
So let's do what those comparisons don't: enumerate what teams actually use data-plane extensions for, check which of those needs Linkerd covers without writing code, and be precise about the cases where you really do want WASM, because they exist.
What people actually extend proxies for
Strip the abstraction and proxy extension use cases cluster into a short list: traffic routing and shifting, retries and timeouts, authorization and authentication, rate limiting, header manipulation, telemetry collection, and calls to external services like auth servers on the request path.
That list is worth staring at. Almost all of it is configuration, in the sense that thousands of teams need the same behavior with different parameters. The mesh-as-product question is whether those behaviors should be built in and configured declaratively, or whether each platform team should assemble them from filters.
Linkerd's bet is the first answer. Here's where that bet stands.
The built-in coverage, item by item
Routing, shifting, canaries. Linkerd implements the Kubernetes Gateway API types: HTTPRoute and GRPCRoute give you header-based routing, traffic splitting, and dynamic request routing as standard, portable YAML. Canary and blue-green deploys ride on the same machinery, with Flagger and Argo Rollouts integration for progressive delivery.
Retries, timeouts, circuit breaking. Configurable per route, with budget-based retries rather than naive retry counts, plus circuit breaking for marking misbehaving endpoints unavailable.
Authorization. Default-on mTLS with workload identity feeds authorization policy at namespace, workload, port, route, and gRPC-method granularity. Identity-based, deny-by-default if you want it, all CRDs.
Rate limiting. Built in since Linkerd 2.17, which also added egress visibility and control for traffic leaving the mesh.
Telemetry. Golden metrics (success rate, request rate, p50/p95/p99 latency) for every workload and route, plus distributed tracing, without instrumenting anything.
That's the overwhelming majority of the extension list, shipped as supported product features, configured with kubectl, documented in one place, and upgraded for you when the mesh upgrades.
What "configuration, never code" looks like in practice
Two examples, because the abstract argument lands harder with YAML attached.
A canary shift that an Istio shop might assemble with routing config and possibly custom filter logic is, in Linkerd, a Gateway API HTTPRoute splitting traffic by weight:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: payments-canary
namespace: prod
spec:
parentRefs:
- name: payments
kind: Service
group: core
port: 8080
rules:
- backendRefs:
- name: payments-stable
port: 8080
weight: 90
- name: payments-canary
port: 8080
weight: 10Apply it, watch the canary's success rate and p99 in your existing dashboards, and adjust the weights. Roll back by deleting the resource. Nothing in that workflow has a version compatibility matrix with your proxy fleet.
Locking a service down to a single caller, at the route level, is 2 more resources: a Server that selects the workload and sets deny as the default, and an AuthorizationPolicy that allows one mTLS identity:
apiVersion: policy.linkerd.io/v1alpha1
kind: MeshTLSAuthentication
metadata:
name: payments-callers
namespace: prod
spec:
identities:
- "web.frontend.serviceaccount.identity.linkerd.cluster.local"Both examples are reviewable in a PR by anyone who knows Kubernetes, enforced identically in every cluster, and carried forward automatically across every mesh upgrade. That last clause is where the years of cost difference live: a fleet of custom filters has to be revalidated against each proxy version, forever, and Istio's own WASM distribution docs can give you a feel for the machinery involved in doing that well.
The operational difference is the point. A WASM filter is software you now own: you write it (or vendor it), test it against proxy upgrades, version it, distribute it, monitor it, and debug it when a request path misbehaves. Multiply by every cluster and every Envoy version bump. A built-in feature is a line of YAML and somebody else's regression suite. Your custom filter is your pager's problem, and it's on the hot path of every request.
What a fixed-function proxy buys you
The no-extensions design is load-bearing. It pays for 3 things Linkerd is known for.
Performance. The microproxy exists because a general-purpose extensible proxy carries weight that a purpose-built one doesn't. In 2025 benchmarks run on GKE with wrk2, Linkerd was 163ms faster than sidecar Istio at p99 under 2000 RPS, and held an 11.2ms lead over Istio's ambient mode at the same load. (Disclosure: the benchmark was run by a Linkerd Ambassador against the emojivoto demo app with North-South traffic; methodology and raw results are public precisely so you can rerun it on your own workloads.)
Security surface. A proxy that can load and execute external code has a categorically different attack and audit surface than one that can't. Linkerd's data plane is small enough to be independently audited; the 2024 security audit is public. When your compliance reviewer asks "what code can run on the request path," the Linkerd answer is one sentence long. The production version of this argument has numbers attached: when Imagine Learning consolidated on Linkerd, service-mesh-related CVEs dropped by 97% and compute requirements fell by more than 80%.
Predictability. Every Linkerd proxy in every cluster on the same version is running the same code. Behavior under load, memory profile, and failure modes are uniform across the fleet. There's no "well, that cluster has the custom header filter" in your incident retros.
When you genuinely need WASM
You should evaluate Istio's WASM extensibility if:
- You have a real requirement to run your own code inside the proxy: a custom authentication scheme that can't sit at the gateway, an in-house protocol to parse, payload transformation that must happen mesh-wide.
- You're a platform vendor building productized capability on top of the mesh data plane.
- Your organization has standardized on Envoy everywhere and maintains Envoy expertise as a competency.
Those are legitimate, and for them Istio is the better fit. Before you put your whole mesh decision on this axis, ask one question: does the logic have to run in every proxy, or at the edge? Most "we need a custom filter" requirements are actually ingress requirements, and any Envoy-based or otherwise programmable gateway can run them at the boundary while Linkerd handles east-west traffic behind it. The mesh and the edge are separable decisions.
The other WASM question: Linkerd already meshes WebAssembly workloads
"Does the mesh support WASM" is really two questions, and comparison content routinely conflates them. The first is whether you can run WASM code inside the proxy (Istio's extension model, covered above). The second is whether the mesh can serve WebAssembly workloads: server-side WASM components, the kind [wasmCloud](https://wasmcloud.com/) orchestrates, as a first-class citizen alongside your containers.
On that second question, there's third-party evidence worth more than anything we could write ourselves. At Linkerd Day during KubeCon EU 2025 in London, Joonas Bergius, a wasmCloud maintainer and senior engineer at Cosmonic, presented [Meshin' With WebAssembly: Taking Linkerd Beyond Containers] on running wasmCloud's WASM components behind Linkerd. His verdict, verbatim: "honestly, I was a little disappointed because it just works." With things configured correctly, he found you get "the vast majority of the benefits of Linkerd out of the box" for WebAssembly workloads, crediting the design decisions and extension points Linkerd exposes.
He also named the open edges, and they're worth repeating because they're honest and they're not Linkerd-specific. A multi-tenant WASM host runs many components behind a single IP and a single workload identity, so per-component authorization policy and per-component observability are open problems for any mesh today. The integration path he pointed at is SPIFFE and SPIRE, the same identity machinery Linkerd's [mesh expansion](https://linkerd.io/2024/02/21/announcing-linkerd-2.15/ ) already uses for VMs, and wasmCloud has [adopted SPIFFE for its workload identity](https://wasmcloud.com/blog/2025-04-01-wasmcloud-at-kubecon-cloudnativecon-europe-2025/ ) as well. The pieces for component-level identity are converging from both sides.
One more thing from that talk, in the interest of the full picture: Bergius also floated the idea of WASM-component extension points for Linkerd's proxy, pointing at open GitHub issues he thought could fit. That's community exploration, and the fixed-function tradeoffs above are why the bar for any such change is high. But it's a useful data point about where the conversation actually is: the WASM community treats Linkerd as the mesh its workloads already run behind, and its maintainers are showing up at Linkerd Day to propose going further together.
The extension that matters most arrives as a release
One more pattern worth naming, because it's the strongest practical answer to "but what if we need something the mesh doesn't do?"
Look at what's landed in Linkerd over the last 2 years of releases: mesh expansion to VMs and bare metal in 2.15, egress control and rate limiting in 2.17, GitOps-native multicluster in 2.18, and post-quantum key exchange on by default in 2.19. Rate limiting and egress control sat near the top of the "things teams write filters for" list for years. They arrived as product: documented, supported, tested against everything else in the mesh, and switched on with CRDs.
Compare the two paths for acquiring the same capability. The filter path: your team writes it (or adopts a third-party module), owns its security review, and revalidates it on every proxy upgrade across every cluster, with the engineer who wrote it eventually leaving. The release path: you read the changelog and run the upgrade. The filter path is faster for the first 90 days. The release path is cheaper for the next 5 years, and the 5 years are where platform budgets actually go.
The post-quantum example makes the point sharpest. No platform team's filter backlog had "swap the TLS key exchange for ML-KEM-768" on it, and none could have built it. It shipped to every Linkerd user simultaneously because the data plane is one small, coherent codebase that the maintainers can move all at once. A fixed-function proxy turns out to be the thing you can upgrade fearlessly, and fearless upgrades are how you get next year's security posture without next year's migration project.
The question to ask your own team
Pull up your list of mesh requirements and sort each one into "the mesh ships this as a feature" or "we'd write code." Run the same sort against the Linkerd feature docs and Istio's.
Our read, from years of adoption conversations (an observation, so treat it as one): most platform teams end up with an empty or near-empty "we'd write code" column, and a long column of features they want to work reliably with minimal operational attention. If that's your shape, a fixed-function data plane is a strength masquerading, in vendor comparisons, as a gap. If your "write code" column has real entries that must run mesh-wide, you're in the WASM use case, and you should pick accordingly with eyes open about the maintenance you're signing up for.
Where Buoyant Enterprise for Linkerd fits
Buoyant Enterprise for Linkerd (BEL) doesn't change this calculus; it reinforces the operational premise behind it. The pitch of a fixed-function data plane is that the mesh is a product someone else hardens, and BEL is that promise with a contract attached: stable signed artifacts, SBOM and SLSA provenance on every image, FIPS builds where required, and support from the proxy's authors. Teams choose Linkerd to not be in the proxy business; BEL extends that to not being in the proxy-supply-chain business either.
If a feature you need is missing, the path is the Linkerd roadmap and community, where rate limiting and egress control both landed because enough real users needed them. That's the trade: features arrive as supported product for everyone, at the speed of the project rather than the speed of your own filter-writing sprint.
Common questions
Can I extend Linkerd at all? The data plane, no, by design. Around the mesh, yes: the control plane exposes everything via Kubernetes APIs, metrics are open Prometheus data anyone can build on, and Linkerd extensions add capabilities like Viz and multicluster as separate, optional components. The line Linkerd holds is specifically "no third-party code executing inside the request-path proxy."
What if I need a feature the mesh lacks? Check the roadmap and community first; rate limiting and egress control both shipped because users asked loudly. If it's on the request path and Linkerd doesn't do it, the architectural answer is usually to run it at the edge (gateway) or in the workload, both of which you control fully.
Is the microproxy a fork of Envoy? No, it's a purpose-built proxy written in Rust, designed for exactly one job: being a Linkerd sidecar. That single-purpose design is why it stays small, fast, and auditable, and why a WASM runtime was never bolted onto it.
Does "no WASM" mean Linkerd is behind on the Gateway API? The opposite: Linkerd implements Gateway API types (HTTPRoute, GRPCRoute) as its native configuration surface for routing and policy, which means your traffic configuration is portable Kubernetes standard, not mesh-specific DSL.
Who actually wins from the extensibility framing? Worth asking. A maximally extensible data plane benefits the teams with the engineering budget to exploit it, vendors building on it, and the comparison-matrix author who gets another checkbox. The 4-person platform team running 30 clusters benefits from the opposite property: a data plane whose entire behavior is documented, supported, and identical everywhere. Be honest about which team yours is; both answers are respectable, and they point at different meshes.
Try the boring path first
Take your hardest "we'd need a custom filter" requirement and spend an hour trying to express it as Linkerd policy and Gateway API resources. The docs for authorization policy, HTTPRoute, and rate limiting are the place to start. If it fits, you've just deleted a software project from your team's backlog. If it doesn't, you've learned something specific about your requirements, which beats choosing a mesh off a feature-matrix checkbox either way.
Got a requirement you're not sure fits the config-not-code model? Contact us and we'll give you a straight answer, including when the answer is "that's a WASM use case."
Sources: Istio WasmPlugin reference · Istio extensibility concepts · Why Linkerd doesn't use Envoy · Announcing Linkerd 2.17 · Linkerd vs Ambient Mesh: 2025 Benchmarks · Linkerd 2024 Security Audit · Imagine Learning case study
Frequently asked questions
Can Linkerd mesh WebAssembly workloads?
Yes. At Linkerd Day EU 2025, a wasmCloud maintainer evaluated WASM components running behind Linkerd and reported it just works, with most benefits available out of the box. Per-component identity and observability in multi-tenant WASM hosts are the open edges, with SPIFFE as the likely path.
Does Linkerd support WASM plugins?
No, by design. Linkerd's Rust microproxy is fixed-function and can't load external code. Routing, retries, authorization, rate limiting, and egress control are built-in features configured through CRDs and the Gateway API instead of custom filters.
How do I run canary deployments in Linkerd without custom filters?
With a Gateway API HTTPRoute that splits traffic by weight between stable and canary backends. Apply the YAML, watch success rate and p99 in your existing dashboards, adjust weights, and roll back by deleting the resource.
Why doesn't Linkerd use Envoy?
Linkerd built a purpose-built Rust microproxy for one job: being a Linkerd sidecar. That keeps it small, fast, and auditable, with less code on the request path. The tradeoff is no filter or WASM extension model, which Linkerd treats as a feature.
Does Linkerd support rate limiting and egress control?
Yes. Both shipped as built-in features in Linkerd 2.17 (December 2024), configured declaratively. They were 2 of the most common reasons teams wrote custom proxy filters; in Linkerd they arrive as supported product instead.