FIVE9S
Field notesResilient Infrastructure

Cloud-native, and what it actually cost

Microservices, containers, and orchestration brought real agility and charged for it in operational surface. The pattern is settled; the bill is the part still worth arguing about.

The argument is over. That is the interesting part.

Cloud-native stopped being a position about a decade ago. Containers, an orchestrator, declarative infrastructure, and a delivery pipeline are now what a competent team reaches for by default, and nobody senior is being asked to justify the choice. That is genuine progress, and it is also why the conversation worth having has moved.

The claims made for the pattern were mostly true. Independent deployability really does let teams ship without a release train. Independent scaling really does stop you buying capacity for your busiest component and applying it to everything else. Failure really is more likely to be partial. Iteration really is faster once the pipeline exists.

What the pitch left out is that each of those came with an invoice, and the invoices are recurring. A decade in, most of the estates we are called into are not struggling with whether to be cloud-native. They are struggling with the standing cost of being cloud-native at a scale that never justified it.

What each era brought, and chargedMost estates are somewhere in 03–04Fig. 05
  1. 01Monolith on tinOne thing to reason aboutOne thing to bring down
  2. 02VirtualisedCapacity in minutesDrift, per host, forever
  3. 03ContainerisedThe same artifact everywhereA supply chain to defend
  4. 04OrchestratedScheduling, healing, rollbackA distributed system to operate
  5. 05PlatformedOne paved road per teamA product needing an owner

Which patterns actually survived contact

Every cloud-native list contains the same eight or nine items, weighted equally, as though a team should adopt them together. They should not. Some pay for themselves on day one at any size; others only make sense past a threshold most organisations never reach.

Roughly in the order we would introduce them:

Containers
The one that paid for itself immediately. A build artifact that runs the same on a laptop and in production removed an entire category of argument. It also handed you a supply chain: every image is a dependency tree somebody has to answer for when the next advisory lands.
Continuous delivery
The pattern that makes the rest safe. Small changes, frequent, automatically verified, individually reversible. If deployment is still an event with a calendar invite, the architecture underneath it is not the thing holding you back.
Declarative infrastructure
Terraform, Bicep, or Cluster API — the specific tool matters far less than whether the state file is authoritative. Infrastructure that is described in code but edited in a console is worse than infrastructure that was never described at all, because now you trust it.
Orchestration
Scheduling, health checking, and rollback stopped being things each team wrote badly by hand. In exchange you now operate a distributed control plane, and the failure modes that matter moved from the application into the scheduler.
Observability
Not the same as monitoring, and not optional once requests span more than three processes. Traces first, then metrics, then logs — in that order, because in a distributed system the question is almost always “where did this request go” rather than “what is the CPU doing”.
Microservices
Worth it at the boundary where two teams genuinely need to ship independently. Below that boundary it converts a function call into a network call with a timeout, a retry policy, and a new way to be down. Most estates we see have roughly twice as many services as they have teams to own them.
Service mesh
The one we most often talk teams out of. mTLS, traffic shifting, and per-hop telemetry are real, but so is a second control plane in the request path. Below roughly thirty services, ingress plus a decent library usually buys you the same thing for a fraction of the operational surface.

Adopt the whole list because the list exists, and you have bought the operational cost of a hundred-engineer estate to run a twelve-engineer one.

Why Kubernetes won, honestly

Kubernetes is the default because it is the schema everyone agreed on, not because it is pleasant. Its API is the lingua franca that let a genuine ecosystem form: ingress, secrets, policy, autoscaling, and GPU scheduling all became things you configure rather than things you build. Vendor neutrality is the underrated half of that — the same manifests run on EKS, AKS, GKE, and a rack in a datacentre, which is worth real money at contract-renewal time.

The self-healing story is also true and routinely oversold. Kubernetes will restart your crashed container and reschedule it onto a healthy node. It has no opinion about whether your application was correct before it crashed, and a crash loop behind a passing liveness probe is a system confidently reporting health while serving nothing.

Take it for the scheduling, the rollback semantics, and the ecosystem. Do not take it expecting reliability to be included. Reliability is an SLO, an error budget, and a release process that respects both — Kubernetes is where you implement that, not a substitute for having it.

What it charges you

These are the four bills that come due, in roughly the order teams discover them. None is an argument against the pattern. All four are arguments for adopting it deliberately rather than by drift.

Complexity moves, it does not leave
A monolith concentrates complexity in a codebase, where a debugger works. A distributed system spreads it across a network, where one does not. That trade is often correct. It is never free, and teams that made that trade for organisational reasons are frequently surprised to be paying for it technically.
The security surface multiplies
Every service is an identity, every call is an authorisation decision, and every image is a bill of materials. Cluster-level RBAC and network policy are the floor, not the ceiling. The practical test: when a CVE drops on a base image, can you answer “are we affected” from a record you already hold, in minutes?
Someone has to own the platform
The most common failure we are called into is not technical. It is a cluster that three teams depend on and nobody is funded to run. Cloud-native infrastructure is a product with users; unowned, it degrades into whatever version each team patched locally.
The skills gap is real and it is expensive
Containerisation, orchestration, and policy-as-code are learnable, but not on the side of a delivery deadline. Budget the training or budget the hiring. Budgeting neither is how you end up with one engineer who understands the cluster and a bus factor of one.

Where we would actually draw the line

Containers and a delivery pipeline: yes, at any size, immediately. The consistency and the reversibility are worth more than they cost from the first week, and neither commits you to anything else on the list.

A managed orchestrator: yes, once you have more than a handful of services or any real variability in load. Managed, not self-run — EKS, AKS, or GKE remove the control-plane work that has almost no strategic value and a great deal of operational risk.

Microservices: only at a boundary where two teams are genuinely blocking each other. Not per domain object, and not because the diagram looks better. A well-factored modular monolith deployed twenty times a day is a better outcome than nine services deployed monthly.

A service mesh, a platform team, a multi-cluster topology: when the pain is measurable and named. The signal is queueing — engineers waiting on environments, the same module copied into a ninth repository, an incident whose first thirty minutes are spent working out which service is at fault. Until something is queueing, these are costs with a roadmap attached.

The pattern is settled. The decision left is how much of it your estate is actually big enough to pay for.

Bring us the estate that outgrew its architecture.