All articles
13 September 2026
7 min read

Does the legacy application belong on Kubernetes?

By Tim Rutte, Cloud & Software ArchitectTopicBackend & Platforms

A large tool case with cut-outs for thirty tools; only one is filled, a wrench with a blue handle.

The moment a legacy system is up for modernization, Kubernetes is in the room. Sometimes as a directive from above, sometimes as a wish from the team, often as a given: we containerize it and put it on a cluster.

The question being skipped is not whether Kubernetes is good. It is a mature piece of technology that solves its problem. The question is whether you have that problem.

This article names three conditions under which the platform pays for itself, and shows what does the same thing more cheaply before that. It is not written against Kubernetes but against the order in which the decision usually gets made.

The groundwork without which none of these platforms helps is covered in Sessions, uploads, state.

What has to happen first, wherever you are going

Before the target platform is even up for debate, there is groundwork that applies in every case, and it is the actual modernization.

The application must not put anything on its file system that it expects to find again later. It has to read its configuration from the environment rather than from a file on the server. It has to be able to run more than once without losing sessions. It has to say on startup whether it can work, and finish its in-flight requests on shutdown.

None of that is specific to Kubernetes. It applies just as much to two virtual machines behind a load balancer, to a managed container service, and to whatever platform exists in five years. And it is the part that costs weeks. Swapping the platform underneath costs days.

Reverse the order and build the cluster first, and in three months you have a cluster running an application that tolerates exactly one instance. That is more expensive than before and can do less.

Three conditions under which it pays

Kubernetes solves problems that only appear above a certain size. Three of them decide it in practice, and what they share is that without a platform you would have to answer them with something homegrown.

Many services with rhythms of their own. From around ten to fifteen independently released services, managing the routing, certificates and assignments becomes work in itself. That is exactly what the platform is built for.

Demand that changes by the hour. Not the difference between day and night, which a schedule covers, but load spikes you cannot predict, and a ratio between quiet and peak of ten to one or more.

An operations team that runs it. The most uncomfortable of the three. A cluster is itself a system with versions, end-of-life dates, a network model and failure modes of its own. Whoever runs it runs two systems from now on instead of one.

Miss one of the three and there is usually something simpler that does the same. Miss the third and the platform is the wrong choice regardless of the other two, or it gets bought as a managed service.

What the cluster demands in knowledge

The third condition sounds soft and is the hard one. To check it, go through the list that has to exist in-house from the day it goes live.

The network model and how a call from outside reaches a service. The storage classes and what happens to a volume when a node disappears. The permission model inside the cluster, which is a second world of permissions next to the cloud provider's. The versions: a cluster gets a new one several times a year, and each can remove interfaces an add-on still uses. And the nodes themselves, their operating systems and their end-of-life dates.

None of that is unsolvable, and much of it can be bought as a managed offering. The point is a different one: every line on that list is a responsibility in the team from now on, and it comes on top of the application nobody fully knew before. Modernize a legacy system and introduce a platform at the same time and you have two projects with separate risks and a team learning both on the side.

So the usable order is to separate them: first get the application to where it can run more than once, then decide at leisure what to run it on.

What sits between two machines and a cluster

The decision usually gets framed as a choice between two extremes: everything stays as it is, or cluster. There is more in between than the discussion allows.

Containers without orchestration. Building an image is valuable on its own: it makes the environment reproducible, makes the difference between test and production visible, and is the groundwork for any later platform. Two machines starting the same image is a viable operating state.

A managed container service. Anyone who wants containers without running a cluster gets an intermediate step from every large provider that handles image, scaling and rollout at zero operational cost. For a single monolith that is the right answer in most cases.

Two machines and a load balancer. Underrated and entirely sufficient for many systems. It covers releases without downtime, a way back in a minute and switching in steps, and the operational effort is the one the team already knows.

These three cover the needs of the vast majority of applications that sit on a server today. The jump to the platform only pays once the number of services forces it.

That a release without downtime needs no orchestration is covered in Blue/green and canary without Kubernetes.

When the decision has been made anyway

Sometimes the question is no longer open. The group runs a cluster, the platform is mandated, and the application is going there. That is a legitimate reason, and then only the order matters.

The order is the same as above, just with a known destination. First make the application run more than once, then the image, then the readiness answer, then the move. The move is the shortest part.

Two things regularly take more time than planned, and neither has anything to do with the application. One is the batch jobs and scheduled tasks that sit in a cron file on the old system and need an object of their own with error handling of their own on the platform. The other is outbound access: fixed source addresses, database allow-lists, certificates from partners. In a cluster the address a call comes from changes, and the allow-list at the partner runs through their form, not through your pipeline.

The question to answer first

So that the decision does not end in a matter of taste, one question helps, and it is uncomfortably concrete.

Which problem that we have today goes away, and how would we notice?

If there is an answer with a number in it, the decision is made and justified. If the answer is "we would be more modern" or "everyone does this", then it is not a decision but a purchase, and it costs three months that are missing elsewhere.

What would be possible in that time instead is rarely exciting and almost always more effective: make the application run more than once, release without downtime, have a way back that is a switch. How I build delivery pipelines is described on its own page.

This article continues a series about systems that already exist. The retrospective on the first three months orders its articles by situation.