intermediate 3 min answer Multiple choice

A platform with 40 services on Kubernetes needs mutual TLS between services, uniform retry and timeout behaviour, and per-call telemetry, without modifying 40 codebases in 6 languages. Which placement should the team choose first?

sidecarservice meshmtlsretrieskubernetes
Pick one
Show the full answer Hide the answer

The deciding property

Six languages. That single fact removes the library option and makes the decision almost mechanical. Any approach requiring code in each service must be implemented and maintained six times, upgraded six times, and will drift as one language's implementation lags.

The second deciding fact is that the requirement is service-to-service, which removes the gateway-only option: an ingress gateway sees north-south traffic and nothing that happens between services behind it.

Why the sidecar

It intercepts traffic in the pod's network namespace, so the application sends plain HTTP to a local address and the proxy does the TLS, the retry policy and the telemetry. The policy lives in one place, in one implementation, and applies identically to all six languages, which is exactly the constraint in the stem.

It also gives per-service isolation of the proxy itself: a misconfigured policy affects one pod's sidecar, and a sidecar crash takes down one pod rather than every pod on a node.

The costs are real and knowable in advance. Each sidecar holds its own copy of the routing configuration and its own connection pools, so memory is per pod rather than per host: a few tens of megabytes each, which at 2,000 pods is tens of gigabytes of fleet memory before a request is served. Each hop adds a local proxy on both sides, typically a few milliseconds of p99 per hop, which matters on a path with 5 hops and a 100 ms budget.

Why the other options fail

Node-level shared proxy. This is the newer ambient model and it is genuinely cheaper: one proxy per host rather than per pod, so the memory and configuration cost scales with nodes rather than pods. It fails as a first choice because the blast radius is a whole node's traffic, the identity story is harder (the proxy must authenticate on behalf of many workloads), and per-workload policy is less isolated. It is the right migration once the sidecar model is understood and the fleet cost is measured, not the thing to learn on.

A client library per service. Correct in a single-language estate, and the usual answer before sidecars existed. Here it is six implementations, six upgrade cycles, and a guaranteed gap: the service written last year in the language nobody maintains will be the one still sending plaintext. Library upgrades require a release of every service, so a policy change takes a quarter.

Gateway only. It secures the edge and leaves the inside flat. The specific failure this produces is a service configured to trust any request arriving on the internal network, because the gateway strips credentials and nothing re-establishes them. A batch job inside the cluster then has the authority of an authenticated user.

When this is the wrong choice, and what would flip it

For a single-language estate, or for fewer than about 5 services owned by one team, the sidecar is over-engineering: the operational surface of a mesh exceeds the policy problem it solves.

If this changes Choose Because
One language, one framework A client library No multiplication; no extra hop or memory
Fleet memory or per-hop latency becomes the binding cost Node-level proxy Cost scales with nodes not pods
Only north-south traffic needs policy Gateway only A mesh for 40 services to protect the edge is pure overhead
Fewer than about 5 services, one team Nothing yet The operational surface of a mesh exceeds what it buys