Service Mesh in 2026: Istio Ambient vs Linkerd vs Cilium, Do You Need One?

Oct 31, 2026 · 13 min · Ajay Kumar

Every few months someone asks me whether they should put a service mesh on their Kubernetes cluster, and in 2026 the honest answer has changed more than the question has. The sidecar tax that made people resent meshes is now optional: Istio's ambient mode has been generally available since November 2024 and the current release is 1.31.3, Cilium has replaced its own mTLS design with Istio's ztunnel, and Linkerd still runs sidecars but ships stable builds only through Buoyant. Meanwhile AWS switched App Mesh off on 30 September 2026. This post covers what a service mesh does today, what sidecar and sidecarless designs cost according to the published measurements, where Istio ambient, Linkerd and Cilium actually stand, how Gateway API became the shared configuration language, and when you should not run a mesh at all.

What does a service mesh actually do in 2026?

Strip the marketing and a mesh does four jobs. It gives every workload a cryptographic identity (a SPIFFE ID derived from the Kubernetes service account) and uses it for mutual TLS between pods. It enforces authorization by that identity rather than by IP. It manages traffic: retries, timeouts, weighted splits. And it emits uniform telemetry for every hop.

What changed is where the proxy runs. There are now three shapes:

  • Sidecar per pod. Istio's classic mode and Linkerd. Every pod carries its own proxy.
  • Per-node L4 proxy plus optional L7 proxies. Istio ambient puts a ztunnel on each node for mTLS and L4 policy, and adds Envoy-based waypoint proxies only where you need HTTP features. Cilium does L4 in eBPF and L7 in a per-node Envoy.
  • Native sidecars. Kubernetes promoted sidecar containers to stable in v1.33, which fixed the old startup-ordering and Job-termination bugs. Istio 1.27 made native sidecars the default for eligible pods, and Linkerd 2.20 did the same for proxy injection.

Native sidecars fix lifecycle, not cost: still one proxy per pod.

Is Istio ambient mode production ready?

For the core, yes. The GA announcement on 7 November 2024 marked ztunnel, waypoints and the APIs Stable after 26 months of work. ztunnel is a purpose-built Rust proxy that only does L4: it wraps pod traffic in HBONE (HTTP CONNECT over mTLS on port 15008), checks identity-based policy at the destination node, and stays out of HTTP entirely.

The feature status page has the honest detail. Stable: ztunnel core, waypoint core, AuthorizationPolicy, PeerAuthentication, and HTTPRoute/GRPCRoute on waypoints. Beta: multi-network multicluster, dual-stack and IPv6, cross-namespace waypoints, DNS proxying. Alpha: VirtualService on waypoints, TCPRoute/TLSRoute, and WebAssembly plugins. If your current config is mostly VirtualService, the migration includes rewriting it as HTTPRoute.

Istio 1.31 shipped in late August 2026 with weighted waypoint canaries (send, say, 5% of connections to a new waypoint first), CPU-aware ztunnel worker threads, a long list of multicluster leak fixes, and the option to run agentgateway, a proxy purpose-built for AI agent and MCP traffic, as a waypoint. That one is experimental, but it puts agent-to-tool traffic under the same identity and policy plumbing as everything else, which is where it belongs. The 1.31.3 patch followed on 21 October with security advisory ISTIO-SECURITY-2026-008. Per the support table, 1.31 is supported until roughly February 2027 on Kubernetes 1.32 to 1.37, and 1.29 reached end of life on 15 October.

Two operational warnings. First, Istio is retiring its GCP-hosted artifacts (gcr.io/istio-release and the old Helm bucket) with deliberate outage "scream tests" on 17 November and 8 to 9 December 2026; pipelines on the old URLs will break those days. Second, the sidecar-to-ambient migration guide states plainly that zero-downtime migration is not supported when L7 policies are involved, and recommends a maintenance window.

Sidecar vs sidecarless: what does the overhead actually cost?

Start with the vendor's own numbers. Istio's performance page (measured on 1.24, 1,000 HTTP requests per second, 1 KB payloads, mTLS on) puts a sidecar at about 0.20 vCPU and 60 MB, a ztunnel at about 0.06 vCPU and 12 MB, and a waypoint at about 0.25 vCPU and 60 MB. Per proxy, a waypoint is not cheaper than a sidecar. The saving comes from the multiplier: sidecars scale with pods, ztunnels with nodes, and waypoints with however many namespaces or services actually need L7.

For your cloud bill, requests matter more than usage, because requests are what the scheduler reserves. In the Istio 1.31.3 charts, each sidecar requests 100m CPU and 128Mi by default, and each ztunnel requests 200m CPU and 512Mi. Take 400 pods on 20 nodes: sidecars reserve 40 vCPU and 50 GiB before serving a single request, while ztunnels reserve 4 vCPU and 10 GiB, plus whatever waypoints you add. That is arithmetic on defaults, not a measurement, and many teams tune sidecar requests down.

The best independent comparison I know is a technical report from Tel Aviv University and Red Hat researchers (November 2024). On a single GCP cluster with mTLS enabled, P99 latency at 3,200 requests per second rose 166% with Istio sidecars, 99% with Cilium, 33% with Linkerd and 8% with Istio ambient, against a 0.22 second baseline. Istio sidecars could not reach the 12,800 RPS target and topped out at 6,868. Read it with three caveats: the paper does not list mesh versions, its tables do not exactly match the percentages in its text, and Cilium skipped intra-node encryption, which flatters it on same-node traffic. Ambient also ran without a waypoint, so it was doing L4 only.

That last point matters. Linkerd's own 2025 benchmark, run by a Linkerd ambassador with ambient's waypoint enabled for parity, found Linkerd 11.2 ms ahead of ambient at P99 and 163 ms ahead of sidecar Istio at 2,000 RPS. Vendor benchmark, so discount accordingly, but the shape is consistent: ambient L4 is very cheap, and adding a waypoint puts an Envoy hop back in the path.

Before arguing about any of this, measure what your sidecars reserve today. This counts both classic and native sidecars (native ones live in initContainers):

# Requires kubectl and jq 1.7+. Read-only: sums the requests of istio-proxy and linkerd-proxy containers.
kubectl get pods -A -o json | jq '
  def cpu_m:  if . == null then 0 elif endswith("m") then (.[:-1] | tonumber) else (tonumber * 1000) end;
  def mem_mi: if . == null then 0
              elif endswith("Gi") then (.[:-2] | tonumber * 1024)
              elif endswith("Mi") then (.[:-2] | tonumber)
              elif endswith("Ki") then (.[:-2] | tonumber / 1024)
              else (tonumber / 1048576) end;
  [ .items[]
    | (.spec.containers + (.spec.initContainers // []))[]
    | select(.name == "istio-proxy" or .name == "linkerd-proxy")
    | .resources.requests // {} ]
  | { sidecars: length,
      cpu_requested_cores: ((map(.cpu | cpu_m) | add // 0) / 1000),
      memory_requested_gib: ((map(.memory | mem_mi) | add // 0) / 1024 * 100 | round / 100) }'
# Example output: { "sidecars": 3, "cpu_requested_cores": 0.3, "memory_requested_gib": 0.27 }
What a mesh costs: added P99 latency and per-proxy resources P99 latency added, 3,200 RPS Istio sidecar +166% Cilium (no intra-node enc.) +99% Linkerd +33% Istio ambient (ztunnel only) +8% vCPU per 1,000 RPS (Istio 1.24) sidecar, one per pod 0.20 vCPU, 60 MB waypoint, per namespace 0.25 vCPU, 60 MB ztunnel, one per node 0.06 vCPU, 12 MB The multiplier decides the bill: sidecars scale with pods, ztunnel with nodes, waypoints with L7 scopes. Istio 1.31.3 chart defaults: sidecar requests 100m CPU and 128Mi; ztunnel requests 200m CPU and 512Mi.
Top: P99 latency increase at 3,200 RPS as stated in the text of arXiv report 2411.02267 (versions not listed; Cilium skipped intra-node encryption). Bottom: Istio's published per-proxy cost at 1,000 RPS, measured on Istio 1.24.

Linkerd in 2026: still sidecars, and who ships stable releases

Linkerd is still the mesh I would hand to a small team that wants mTLS and golden metrics without learning Envoy. Its proxy is a Rust micro-proxy built for this one job. The change that matters is commercial. Since February 2024, per the releases page, "the Linkerd open source project itself no longer provides stable release artifacts." The open source project publishes edge releases several times a month (the latest is edge-26.10.2, from 29 October), and stable, semver builds come from vendors, in practice Buoyant Enterprise for Linkerd.

Buoyant's FAQ says companies with fewer than 50 employees can run BEL free in production, without support. Above that, production use needs a paid licence, and the pricing page now lists Premium and Strategic plans behind a contact form rather than public prices. If you are above 50 people, your real choice is between paying Buoyant and running edge releases with your own upgrade testing.

The technical side is in good shape. Linkerd 2.19 (31 October 2025) moved the proxy's crypto to aws-lc and made ML-KEM-768 post-quantum key exchange the default between meshed pods, which makes it the easiest mesh to point at when someone asks about post-quantum migration. Linkerd 2.20 (23 June 2026) added rate-limit-aware load balancing that respects HTTP 429 and gRPC RESOURCE_EXHAUSTED, cut destination controller memory "in some cases by almost 85%", and made native sidecars the default. It supports Kubernetes up to 1.35, so check that before your next cluster upgrade.

Cilium service mesh: from eBPF mutual auth to ztunnel

Cilium's pitch was always that your CNI is already on every node, so why add another proxy layer. It handles L4 in eBPF and runs a per-node Envoy for L7 (the eBPF side is in my eBPF explainer).

The mTLS story changed this year. Cilium 1.19 (4 February 2026) disabled its out-of-band Mutual Authentication feature by default and introduced a beta ztunnel integration; the 1.20 upgrade notes then deprecated Mutual Authentication outright. Cilium's own Helm values describe ztunnel as "Istio's purpose-built, per-node proxy." So the two biggest sidecarless designs now share the same L4 component, which is a quiet vote for ambient's architecture.

The ztunnel encryption docs list real limits: beta, TCP only, namespace-level enrolment via the io.cilium/mtls-enabled=true label, no Cluster Mesh, and traffic is only supported when both ends are enrolled. Cilium 1.20 (29 July 2026) added SPIRE or internal CA identities for ztunnel and moved to Gateway API v1.6.1. The latest patch is v1.20.4 from 23 October. If all you need is encryption in transit between nodes, Cilium's WireGuard encryption gets you there with no mesh at all, though without per-workload identity.

Gateway API is now the service mesh configuration language

The other quiet convergence is configuration. The GAMMA work, which lets a route attach to a Service instead of a Gateway, reached the standard channel in Gateway API v1.1 in May 2024. The implementations page now lists Istio (v1.6.0) and Cilium (v1.6.1) as mesh-conformant, and Linkerd 2.20 supports HTTPRoute and GRPCRoute from Gateway API 1.2.1 to 1.5.1. This is the same API family that replaced Ingress, which I wrote about after ingress-nginx was retired.

A canary split that works, modulo version support, on all three:

# Gateway API v1 HTTPRoute bound to a Service (GAMMA). On Istio ambient this is enforced by a waypoint,
# so the namespace or Service needs istio.io/use-waypoint first. Cilium 1.20 and Linkerd 2.20 apply it directly.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: reviews-canary
  namespace: shop
spec:
  parentRefs:
  - group: ""          # core API group, because the parent is a Service, not a Gateway
    kind: Service
    name: reviews
    port: 9080
  rules:
  - backendRefs:
    - name: reviews-v1
      port: 9080
      weight: 90
    - name: reviews-v2
      port: 9080
      weight: 10

Write new mesh config as Gateway API resources rather than VirtualService or ServiceProfile, and switching meshes later becomes a data plane migration, not a rewrite of every route.

Istio ambient vs Linkerd vs Cilium: comparison table

Istio ambient Linkerd Cilium service mesh
Latest release (Oct 2026) 1.31.3 2.20 stable via Buoyant; edge-26.10.2 1.20.4
Data plane ztunnel per node (Rust), Envoy waypoints for L7 Rust sidecar per pod, native sidecar by default eBPF, per-node Envoy for L7
mTLS status Stable since 1.24 (GA post) On by default for meshed pods; ML-KEM-768 since 2.19 ztunnel beta; old mutual auth deprecated in 1.20
L7 policy and routing Waypoint required In every sidecar Per-node Envoy
Gateway API mesh Conformant v1.6.0 HTTPRoute, GRPCRoute (API 1.2.1 to 1.5.1) Conformant v1.6.1
Stable builds Free, CNCF project Free under 50 employees, otherwise paid licence (FAQ) Free, CNCF project
Biggest caveat No zero-downtime sidecar migration with L7 policy Licensing for larger companies ztunnel mTLS is TCP-only, no Cluster Mesh

Do you need a service mesh at all?

Plenty of teams have decided no. CNCF's State of Cloud Native Development report, based on a SlashData survey of over 12,000 developers, found backend developer use of service meshes fell from a peak of 18% in Q3 2023 to 8% in Q3 2025. The report names CPU cost and mesh features moving into platform teams and other tools as likely reasons. AWS made its own call: App Mesh reached end of support on 30 September 2026, with ECS Service Connect as the suggested replacement.

My rule of thumb:

  • You need workload identity and mTLS for compliance or zero-trust reasons. Istio ambient with ztunnel only is now cheap enough that the old cost argument mostly goes away. Add PeerAuthentication in STRICT mode and identity-based L4 policy.
  • You need per-service L7 policy, retries, or canaries. Add waypoints only to the namespaces that need them, or run Linkerd if you are small enough to use it free or happy to pay.
  • You only need encryption in transit. Use your CNI's WireGuard or IPsec and skip the mesh.
  • You have a dozen services and one team. You probably need NetworkPolicy, sensible timeouts in your HTTP clients, and OpenTelemetry, not a mesh.

A mesh does not replace NetworkPolicy, certificate ownership, or someone who understands the data path at 3 a.m.; it adds a component in front of every request, which is exactly what platform discipline exists for. The AI-era twist is that agents now call internal tools on their own schedule, and per-workload identity policy is the cleanest way to say which agent may call what. That argues for the identity layer even if you never touch L7.

FAQ

Is Istio ambient mode production ready in 2026?

Yes for the core. ztunnel, waypoints, AuthorizationPolicy and PeerAuthentication have been Stable since Istio 1.24 in November 2024. Multi-network multicluster and dual-stack are Beta, and VirtualService on waypoints is Alpha.

Is Linkerd still free and open source?

The code is open source and edge releases are free. Since February 2024 the project no longer publishes stable releases; Buoyant does, free in production for companies under 50 employees and under a paid licence above that.

Does Cilium service mesh support mTLS?

Yes, but the mechanism changed. Cilium 1.19 disabled its original Mutual Authentication feature by default and 1.20 deprecated it in favour of a beta ztunnel integration that encrypts TCP between enrolled namespaces. It does not yet work with Cluster Mesh.

Is a service mesh overkill for a small team?

Usually. With a few services and no compliance need for workload identity, NetworkPolicy, client timeouts and OpenTelemetry cover most of it. If you do need mTLS, Istio ambient without waypoints or Linkerd are the lightest options.

If I were starting this quarter, I would install Istio ambient on a staging cluster with ztunnel only, turn on STRICT mTLS, run the sidecar-request script above against production to put a number on the current cost, and only then decide which namespaces genuinely need a waypoint. New routing config would go in as Gateway API resources whichever mesh wins. The step-by-step version, including the sidecar migration, is in my Istio ambient install and mTLS guide.

Related: eBPF Explained (2026): Verifier, CO-RE, Cilium, Tetragon and sched_ext, Ingress NGINX Is Retired: What Replaces It and How to Choose in 2026 and Workload Identity Federation Explained (2026): OIDC Instead of Cloud Keys.

I'm Ajay Kumar — I build and operate PandaStack, an open-source Firecracker microVM cloud for AI agents, and write about the infrastructure and tooling around it.

Need this kind of infrastructure work? See what I do or email hello@ajayk.sh.


Related