We have built and run Kubernetes for Australian businesses for years, and we still talk roughly a third of enquirers out of it. Not because the technology is bad, since it is excellent at what it is for, but because the business case presented to us usually rests on a cost comparison that omits most of the costs.
If you are weighing a migration, these are the six line items that decide whether it pays for itself. None of them appear in a licensing comparison.
What the quote covers
A typical migration quote covers cluster build, CI/CD pipeline work, containerising the applications, and a cutover. That work is real and the estimates are usually reasonable.
The gap is that building a cluster is the easy, well-understood, highly automatable part. With Terraform and a managed control plane, a production-grade cluster is days of work. It is everything the cluster then touches that consumes the budget.
1. The application rewrite you did not scope
"Containerised" and "container-ready" are different states, and the gap between them is where the first overrun lives.
Anything can be put in a container. Whether it behaves correctly when Kubernetes treats it the way Kubernetes treats things is another matter. Kubernetes will kill your pod, reschedule it onto a different node, run several copies, and restart it at inconvenient moments. Applications that assume otherwise break in ways that look intermittent.
The usual offenders:
- Local filesystem writes. Uploads, caches, generated files, logs written to disk. The container filesystem is ephemeral. Every one of these needs to move to object storage or a volume.
- In-memory session state. Works with one instance. Users get logged out at random with three.
- Configuration read from files on disk rather than the environment, so each environment needs a different image, which defeats the point.
- Slow or dishonest startup. Kubernetes needs to know when your application is genuinely ready. Applications that report ready and then spend forty seconds warming a cache will drop traffic on every deployment.
- Ignoring SIGTERM. Without graceful shutdown, every deploy kills in-flight requests. Users see a handful of errors on each release and nobody connects it to the deployment.
For a modern application already following twelve-factor conventions, this is close to zero work. For a ten-year-old application that has only ever run on a single server, it can be the largest line item in the project. The honest way to find out is to containerise one representative application and run it with three replicas before committing to the full scope.
2. Statefulness
Stateless workloads are what Kubernetes is genuinely, unambiguously good at. State is where the difficulty concentrates.
Databases, message queues, anything holding data needs persistent volumes, which means storage classes, access modes, backup and restore that understands the abstraction, and a plan for what happens when a node dies mid-write. Kubernetes has good primitives for this. They are still meaningfully harder to operate correctly than a database on a VM with a backup job that has worked since 2019.
The pragmatic answer
Most of the value with most of the risk removed: run stateless workloads in Kubernetes and keep state in managed services such as RDS, Azure Database or managed Redis, or on the VMs where it already works. "Everything in the cluster" is an aesthetic preference, not an engineering requirement, and it is where migrations go badly.
3. Networking and egress
Two distinct surprises here.
The networking model is genuinely new. Services, ingress controllers, network policies, service mesh if you go there, DNS inside the cluster, and how any of it reaches your existing corporate network. Teams comfortable with VLANs and firewall rules are competent but not yet fluent, and fluency takes months.
Cloud egress charges are a real budget item. Traffic leaving a cloud provider is billed, and traffic crossing availability zones frequently is too. A microservice architecture that was one process making local function calls becomes many services making network calls, sometimes across zones. We have seen this turn into a five-figure annual surprise on an otherwise sensible design. It is avoidable with zone-aware routing and sensible service boundaries, but only if someone is thinking about it before the architecture is set.
4. The platform team you now need
This is the cost that most often goes unmentioned, and the one most likely to decide the outcome.
Kubernetes is an operational commitment. Somebody has to own the cluster, understand why a pod is Pending, keep the ingress controller and CNI and monitoring stack current, and be reachable when something breaks at an awkward hour. It is a capability, whether you hire it, train it, or outsource it.
The failure mode is predictable: one enthusiastic engineer drives the migration, becomes the only person who understands the platform, and leaves. What remains is a production system nobody can safely touch. We have been called in to exactly this situation more than once, and it is a far worse position than the VMs they started with.
Before committing, answer plainly: who operates this in eighteen months, and what happens if that person resigns?
5. Version upgrades, forever
Kubernetes releases several times a year and each release has a supported lifetime measured in about a year. Managed services will eventually upgrade you whether you are ready or not.
This means a recurring upgrade cadence, permanently. Each one carries some risk: deprecated APIs your manifests still use, controllers needing matching versions, occasional behaviour changes. It is manageable, and genuinely routine once you have done a few, but it is ongoing work that did not exist when a server sat there running the same OS for four years.
Budget a few days per upgrade, a few times a year, indefinitely. Teams that skip upgrades for eighteen months face a much harder jump across multiple versions at once, usually under time pressure.
6. Debugging gets harder before it gets easier
On a VM, an engineer SSHs in, tails a log, runs top, and forms a hypothesis in two minutes using skills built over a decade.
In a cluster, the process is different. Which pod? Which node did it land on? Was it OOM-killed and restarted before anyone looked? Are the logs shipped somewhere, and is that somewhere searchable? The answers exist and the tooling is good, but the fluency is new and it takes months to rebuild.
Expect mean time to resolution to get worse for a period after migration. This is normal and temporary, but it is real, and it happens precisely when everyone is watching the new platform closely. Plan for it: get centralised logging and metrics working before cutover, not after the first incident demonstrates you need them.
When it is genuinely worth it
None of this is an argument against Kubernetes. We run it, we like it, and for the right shape of problem nothing else comes close.
| Signal | Kubernetes fits | Probably does not |
|---|---|---|
| Number of services | Many, deployed independently | Two or three |
| Deployment frequency | Daily or more | Monthly |
| Load pattern | Variable or spiky | Flat and predictable |
| Teams deploying | Several, wanting autonomy | One |
| Portability | Required across clouds or on-prem | Single environment, staying there |
| Ops capability | Exists or is being funded | One person, part-time |
The strongest business cases we have seen were not about infrastructure cost. They were about deployment velocity, with teams going from fortnightly releases to several a day, and about consistency, where dev, staging and production finally behaved identically and a category of bug disappeared.
Those are real, valuable outcomes. They are just not the outcomes in a cost-comparison spreadsheet, and pitching a migration on infrastructure savings tends to end with an awkward conversation about the bill twelve months later.
If someone has quoted you a Kubernetes migration, ask them which of these six they have scoped. A good answer will be specific about your applications. A vague one means you will be discovering these costs yourself, in production.
Frequently asked questions
Is Kubernetes cheaper than virtual machines?
Usually not on infrastructure alone at small scale, and frequently not overall once platform staffing is counted. Kubernetes wins on density, deployment speed and consistency across environments, not on raw compute cost. Organisations running a handful of services on a few VMs typically spend more after migrating, because the control plane, the platform tooling and the expertise are largely fixed costs.
How long does a Kubernetes migration take?
For a single stateless web application, weeks. For a portfolio of services including stateful components and legacy applications, six to eighteen months is common. The variable that dominates is not cluster build time, which is days, but how much application change is required, particularly around state, configuration and startup assumptions.
What are the hidden costs of Kubernetes?
The six that consistently appear: application changes to become genuinely container-ready; handling stateful workloads; cluster networking and cloud egress charges; ongoing platform engineering capability; a perpetual upgrade cadence as versions reach end of support; and a temporary but real drop in debugging speed while the team learns new failure modes.
Should a small business use Kubernetes?
Often no. If you run a few services with predictable load and deploy weekly, managed container services or well-run virtual machines will cost less and break less. Kubernetes earns its complexity when you have many services, many teams needing to deploy independently, genuinely variable load, or a hard requirement for portability between environments.
What is the biggest mistake in a Kubernetes migration?
Migrating everything. The highest-return approach is to move the workloads that benefit, meaning stateless, frequently deployed, variable load, and deliberately leave the rest. A database that has run happily on a VM for six years is rarely improved by moving into a cluster, and moving it carries most of the project risk.