Split a monolith into 20 microservices and you don't just multiply deployables, you multiply every cross-cutting concern. TLS, retries, timeouts, trace propagation: suddenly each service carries hundreds of lines of networking code that has nothing to do with your business.

That's a shadow codebase, and it's usually the least differentiated code you own. Nobody buys your product because your retry logic is elegant.

The standard fix a shared SDK works until you have more than one language. Then it forks: a Go SDK, a Java SDK, a Node SDK, each implementing "the same" policy slightly differently, each upgrade a rolling migration across every repo.

A service mesh moves all of it into the infrastructure layer:

mTLS + workload identity — automatic certificate issuance and rotation, zero app code [web:4]