Service Mesh Comparison — Istio vs Linkerd vs Envoy Gateway¶
Summary
Canonical comparison of the two service meshes (Istio, Linkerd) and the Gateway API ingress controller (Envoy Gateway) in this knowledge base. Istio and Linkerd manage east-west (service-to-service) traffic with automatic mTLS. Envoy Gateway manages north-south (edge) traffic and is not a mesh. The three are often combined rather than chosen between. All facts below come from the topic pages, which were refreshed on 2026-09-25.
Quick Reference¶
| Dimension | Istio | Linkerd | Envoy Gateway |
|---|---|---|---|
| Type | Service mesh (plus Gateway API ingress) | Service mesh | Gateway API ingress/edge gateway (not a mesh) |
| Latest Version | 1.31.1 (2026-09-21) | 2.20 (2026-06-23); latest edge edge-26.9.3 (2026-09-16) |
v1.9.1 (2026-08-28) |
| Data plane | Envoy sidecars, or ambient: ztunnel (per node, L4) + optional Envoy waypoints (L7) | linkerd2-proxy sidecar per pod (native sidecar by default since 2.20) |
Envoy fleet per Gateway (or one merged fleet) |
| Proxy language | C++ (Envoy), Rust (ztunnel) | Rust | C++ (Envoy) |
| Sidecar-free option | Yes, ambient mode (GA since 1.24, 2024-11) | No | Not applicable (gateway pods only) |
| Kubernetes support | 1.32-1.36 (Istio 1.31) | 1.31-1.35 (2.20) | 1.33-1.36 tested (v1.9) |
| Gateway API version | Built against v1.6.0 (1.31) | Supports 1.2.1-1.5.1 (2.20) | Bundles v1.6.1 (v1.9) |
| Release model | Quarterly minors; each supported until 6 weeks after the N+2 minor | OSS ships weekly or near-weekly edge releases only; stable semver builds come from vendors (Buoyant Enterprise for Linkerd) | Minor about every 3 months; about 6 months of support per minor |
| License | Apache-2.0 | Apache-2.0 (code and edge artifacts); BEL stable builds need a Buoyant license key | Apache-2.0 |
| Governance | CNCF Graduated (2023-07-12); multi-vendor maintainers | CNCF Graduated (2021-07-28); all maintainers work for Buoyant | Sub-project of Envoy (CNCF Graduated); multi-vendor maintainers |
Gateway API CRDs are shared cluster state
Istio and Linkerd (since 2.19) expect you to install the Gateway API CRDs yourself. EG's Helm chart bundles them, but Helm does not upgrade CRDs, so upgrades are manual. The supported ranges differ: EG v1.9 expects v1.6.1, Istio 1.31 builds against v1.6.0, and Linkerd 2.20 documents 1.2.1-1.5.1. Check every consumer's range before you upgrade the CRDs in a cluster that runs more than one of them.
Data Plane Architectures¶
The diagram shows where the proxies sit in each model: one proxy per pod (Istio sidecar mode and Linkerd), one proxy per node plus optional L7 waypoints (Istio ambient), and a shared edge fleet in front of the cluster (Envoy Gateway).
flowchart LR
subgraph SIDECAR["Sidecar model: Istio sidecar mode, Linkerd"]
direction LR
SA["app A"] --> SPA["proxy in pod A<br/>Envoy or linkerd2-proxy"]
SPA -->|"mTLS, L4 + L7 in every proxy"| SPB["proxy in pod B"]
SPB --> SB["app B"]
end
subgraph AMBIENT["Istio ambient mode"]
direction LR
AA["app A"] --> ZT1["ztunnel on node 1<br/>L4 mTLS"]
ZT1 -->|"HBONE :15008"| WPT["waypoint (Envoy)<br/>optional, L7 only"]
WPT -->|"HBONE"| ZT2["ztunnel on node 2"]
ZT2 --> AB["app B"]
end
subgraph EDGE["Envoy Gateway: north-south"]
direction LR
CLIENT["external client"] --> EGW["Envoy fleet per Gateway<br/>TLS, auth, rate limits"]
EGW --> SVC["Service endpoints<br/>or Backend targets"]
EGC["envoy-gateway controller"] -.->|"xDS :18000"| EGW
end
What the models mean in practice (from the Istio and Linkerd explanations):
- Sidecar: proxy cost scales with pod count, and a request crosses two full proxies. Proxy upgrades require pod restarts. Isolation is per pod, which Linkerd argues is the stronger security boundary.
- Ambient: ztunnel cost scales with node count, and waypoint cost scales with the namespaces or services that need L7. An L4-only request crosses two ztunnels that do no HTTP parsing. Adding a waypoint adds one Envoy hop. Enrolment needs no restart.
- Edge gateway: cost scales with Gateways and replicas, not with workloads. It does not encrypt or police traffic between workloads inside the cluster.
Feature Matrix¶
| Feature | Istio | Linkerd | Envoy Gateway |
|---|---|---|---|
| East-west mTLS | Automatic; PERMISSIVE by default, STRICT via PeerAuthentication; SPIFFE identities |
On by default between meshed pods; TLS 1.3 with hybrid ML-KEM-768 + X25519 key exchange (since 2.19) | Not provided (not a mesh). TLS and client mTLS at the edge, TLS to backends via BackendTLSPolicy |
| L7 routing | Full: header/path matching, weighted splits, mirroring, zone-aware load balancing (Istio APIs or Gateway API) | Gateway API HTTPRoute/GRPCRoute matches and weighted splits; per-request EWMA load balancing | Full Gateway API (HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute) plus HTTPRouteFilter |
| Retries and timeouts | Yes | Yes, as annotations on Gateway API routes (2.16+) | Yes (BackendTrafficPolicy; retry budgets since v1.8) |
| Fault injection | Native (delays and aborts) | Weighted HTTPRoute split to an error-injecting backend | Native (BackendTrafficPolicy delay/abort) |
| Circuit breaking | DestinationRule connectionPool + outlierDetection (mesh-wide default via defaultTrafficPolicy since 1.31) |
Failure accrual per endpoint (2.13+); unified mode that counts 429s (2.20, experimental) |
BackendTrafficPolicy |
| Rate limiting | Local and global via Envoy filters configured with EnvoyFilter (no first-class API) |
Local, inbound HTTPLocalRateLimitPolicy (2.17+); no global limiter |
Local and global (envoy-ratelimit) in BackendTrafficPolicy |
| End-user auth | JWT via RequestAuthentication | Not built in | JWT, OIDC, API key, Basic auth, ExtAuth (SecurityPolicy) |
| Authorization | AuthorizationPolicy (L4 in ztunnel, L7 in sidecar or waypoint) | Server, AuthorizationPolicy, MeshTLSAuthentication, NetworkAuthentication; audit mode | SecurityPolicy authorization (CEL rules since v1.9, GeoIP) |
| Extensibility | TrafficExtension (Wasm + Lua, 1.30+); EnvoyFilter (not on waypoints) |
None (fixed feature set) | EnvoyExtensionPolicy (Wasm, ExtProc, Dynamic Modules; Lua off by default since v1.9); EnvoyPatchPolicy |
| Gateway API role | Ingress, waypoints, and GAMMA mesh routing | GAMMA mesh routing (first Mesh-profile conformant mesh, 2.14); no ingress controller of its own | Ingress (Gateway profile); one of many conformant implementations |
| Multi-cluster | Sidecar multi-primary and primary-remote; ambient multicluster beta (multi-network, multi-primary only, 1.29+) | Gateway, flat pod-to-pod, and federated services; GitOps link-gen (2.18) |
Not applicable |
| Egress control | Egress gateways, ServiceEntry, Sidecar resources | EgressNetwork + Gateway API routes, enforced in the sidecar (2.17+) |
Egress to external targets through the Backend CRD (disabled by default) |
| Non-Kubernetes workloads | VMs with sidecars (ambient does not support VMs) | VMs and bare metal via ExternalWorkload (2.15+) |
Standalone mode on hosts/containers (experimental) |
| Observability | Envoy metrics, OTLP tracing, access logs; Kiali (separate project) | Golden metrics, tap, OpenTelemetry tracing | Envoy metrics, access logs, tracing; egctl for config inspection |
| AI and agent traffic | Gateway API Inference Extension (beta since 1.29); agentgateway as gateway (1.30) and waypoint (1.31), both experimental | Nothing AI-specific | Base layer for Agent Router (formerly Envoy AI Gateway, renamed 2026-09-10); Inference Extension endpoint picker in the two-tier pattern |
Resource and Performance Figures¶
No benchmark compares all three on the same hardware and versions. The sourced numbers below come from different tests and must not be compared as if they were one experiment.
| Data plane component | Scales with | Sourced figure | Source |
|---|---|---|---|
| Istio Envoy sidecar | Pods | ~0.20 vCPU, ~60 MB per sidecar at 1000 RPS, 1 KB payload | Istio 1.24 load tests (Istio reference) |
| Istio ztunnel (ambient L4) | Nodes | ~0.06 vCPU, ~12 MB per ztunnel at 1000 RPS | Same Istio tests |
| Istio waypoint (ambient L7) | Namespaces or services that need L7 | ~0.25 vCPU, ~60 MB per waypoint at 1000 RPS | Same Istio tests |
linkerd2-proxy sidecar |
Pods | 17.8 MB max proxy memory at 2,000 RPS (Linkerd 2.10.2), vs 154.6 MB for an Istio 1.10 sidecar in the same run | Buoyant vendor benchmark, 2021 (Linkerd reference) |
| Envoy Gateway proxy fleet | Gateways and replicas | v1.9.1 release benchmark, one proxy limited to 1 CPU: 21 MiB proxy memory at 10 HTTPRoutes and 400 RPS, 105 MiB at 1,000 HTTPRoutes and about 5,000 RPS | EG release benchmark, 2026-08 (EG reference) |
Numbers removed in this refresh
Earlier versions of this page listed "~20 MB ztunnel", "~10 MB Linkerd proxy", and p99 latencies of ~1 ms / ~3 ms / ~2 ms. None of them had a source, and the ztunnel figure contradicted Istio's published ~12 MB. There is no published benchmark of Linkerd against Istio ambient mode. Benchmark your own workload before capacity planning.
Decision Guide¶
Start from the traffic you need to control. The flowchart reflects the trade-offs on the topic pages; it is a starting point, not a verdict.
flowchart TD
START["Which one should I pick?"] --> EW{"Need mTLS or policy between<br/>services inside the cluster?"}
EW -->|"No, edge traffic only"| EDGE{"Replacing Ingress-NGINX or<br/>adopting Gateway API?"}
EDGE -->|"Yes, want Envoy features"| EG["Envoy Gateway"]
EDGE -->|"Already run a mesh or Cilium"| OWN["Use that project's Gateway API<br/>implementation, or Envoy Gateway"]
EW -->|Yes| EXT{"Need Envoy extensibility (Wasm, EnvoyFilter),<br/>end-user JWT at the mesh, or AI inference routing?"}
EXT -->|Yes| ISTIO["Istio"]
EXT -->|No| SCL{"Want to avoid per-pod sidecars?"}
SCL -->|Yes| AMB["Istio ambient mode"]
SCL -->|No| REL{"Can you track weekly edge releases<br/>or license Buoyant Enterprise for Linkerd?"}
REL -->|Yes| LINKERD["Linkerd"]
REL -->|"No, need OSS semver releases"| ISTIO
ISTIO --> NS{"Also need north-south ingress?"}
AMB --> NS
LINKERD --> NS
NS -->|"Istio"| IGW["Istio Gateway API gateway,<br/>or Envoy Gateway at the edge"]
NS -->|"Linkerd"| LGW["Envoy Gateway (or another<br/>ingress) in front of the mesh"]
| Scenario | Recommendation | Why |
|---|---|---|
| East-west mTLS with the least operational effort | Linkerd | mTLS on by default, few knobs, smallest per-pod proxy in the published benchmark |
| Large mTLS-first mesh, L7 only where needed | Istio ambient | Per-node ztunnel; waypoints only for namespaces that need L7; no restarts to enrol |
| Rich L7 policy, Wasm or custom Envoy behaviour | Istio | TrafficExtension, EnvoyFilter (sidecars), RequestAuthentication |
| Post-quantum key exchange by default | Linkerd | Hybrid ML-KEM-768 + X25519 on all meshed traffic since 2.19 |
| Multi-cluster mesh | Istio or Linkerd | Istio: mature sidecar multi-primary, ambient multicluster in beta. Linkerd: federated services with transparent failover |
| VM workloads in the mesh | Istio (sidecar mode) or Linkerd | Istio ambient does not support VMs; Linkerd uses ExternalWorkload |
| Ingress only, migrating off Ingress-NGINX | Envoy Gateway | Typed policies cover common annotations; ingress2gateway 1.0 has an envoy-gateway emitter |
| LLM, MCP or agent traffic at the edge | Envoy Gateway + Agent Router | Agent Router (formerly Envoy AI Gateway) runs on EG |
| AI inference routing inside the mesh | Istio | Inference Extension beta; agentgateway experimental |
| Must have OSS stable releases, no vendor license | Istio or Envoy Gateway | Linkerd OSS ships edge releases only |
Sidecar-free alternatives outside this domain
Cilium ships a sidecar-free mesh (eBPF plus a per-node Envoy) and its own Gateway API implementation. If Cilium is already your CNI, compare it before adding a separate mesh. See the CNI comparison.
Complementary Usage¶
Istio or Linkerd and Envoy Gateway are not mutually exclusive. A common pattern runs Envoy Gateway at the edge for north-south traffic and a mesh inside for east-west traffic.
- Linkerd + Envoy Gateway: Linkerd has no ingress controller of its own, so an edge gateway is needed anyway. Meshing the gateway's Envoy pods (the approach Linkerd documents for ingress controllers) puts the gateway-to-service hop under Linkerd mTLS. Ingresses that pick pod endpoints themselves (Envoy Gateway resolves EndpointSlices) bypass Linkerd's Service-level L7 routing unless the proxy runs in ingress mode with a destination header such as
l5d-dst-override(Linkerd: Handling ingress traffic). Watch the Gateway API CRD version: EG v1.9 bundles v1.6.1, which is newer than Linkerd 2.20's documented range. - Istio + Envoy Gateway: Istio already includes a Gateway API ingress. Teams add EG when they want EG's policy CRDs (OIDC, API keys, global rate limits) or Agent Router at the edge, independent of the mesh upgrade cycle.
Ingress-NGINX retirement and Gateway API migration
Kubernetes announced the retirement of the community Ingress-NGINX controller on 2025-11-11, and maintenance ended in March 2026 with no further releases or security fixes. Gateway API is the designated successor to Ingress. ingress2gateway 1.0 (2026-03-20) converts Ingress resources, and its envoy-gateway emitter outputs EG policy resources. configuration-snippet, server-snippet and custom Lua do not translate automatically. See Envoy Gateway: migrate from Ingress-NGINX.
Licensing and Release Model¶
- Istio and Envoy Gateway publish Apache-2.0 source and free release artifacts for every supported minor.
- Linkerd code is still Apache-2.0 under CNCF governance, and edge release binaries, images and Helm charts are free. Since February 2024 the open-source project no longer ships stable, semver-versioned artifacts; those come from vendors, mainly Buoyant Enterprise for Linkerd (BEL). According to Buoyant, BEL is free for production use at companies with fewer than 50 employees; larger companies need a paid license. See Linkerd: Licensing and Pricing.
- Support windows: Istio 1.29 reaches EOL on 2026-10-12, and EG v1.8 on 2026-11-08. Both projects force roughly quarterly upgrades.
Sources¶
- Istio documentation, supported releases, 1.31.1 announcement
- Istio performance and scalability and sidecar or ambient?
- Istio: Enabling Rate Limits using Envoy
- Linkerd documentation (edge), Releases and Versions, Announcing Linkerd 2.20
- Linkerd: Handling ingress traffic
- Linkerd: Injecting Faults
- Benchmarking Linkerd and Istio (2021)
- Envoy Gateway documentation, compatibility matrix, v1.9.1 release notes
- Envoy Gateway: Fault Injection
- Gateway API implementations
- Envoy AI Gateway is now Agent Router
- Ingress NGINX Retirement: What You Need to Know
- Repositories: istio/istio, linkerd/linkerd2, envoyproxy/gateway
See Also¶
- Envoy Gateway, Istio, Linkerd
- Service mesh domain overview and comparisons index
- Kubernetes (Gateway API, native sidecars)