All articles
12 September 2026
7 min read

Forty-four articles, five sentences that stayed

By Tim Rutte, Cloud & Software ArchitectTopicLegacy & Modernization

Five cards side by side; the middle one is turned over and blue.

Forty-four articles, all on the same subject: systems that already exist. PHP, Go, AWS, and in between the things that are not technology and decide the outcome anyway.

This text is not a table of contents, that sits at the bottom. It is an attempt to write down what ran through all of the articles without having been planned. Five sentences are left.

The most expensive part is never the code

It started with the question about price and came back in nearly every article afterwards: two systems of the same size differ by a factor of five in effort, and the difference never sits in the amount of code. It sits in what it costs to demonstrate that a change is correct.

More hangs off that than it first appears. Without that demonstration a tool like Rector is limited to the rules the language itself enforces. Without it a coding agent multiplies not the speed but the risk. Without it every revocation of a permission is a gamble and every shutdown of a feature a guess.

So building a net around the place being touched next is not preparatory work you can skip when things are urgent. It is the part that makes everything else cheaper, and the only one that cannot be negotiated away.

An appointment beats an opinion

The second sentence is not about technology, and it looked quite different in three separate articles.

"We should move to a newer version at some point" is an opinion and competes with features. "Maintenance ends on 31 December, the move needs three months of lead time, we start at the end of September" is an appointment and competes with nothing. Same thing, two different conversations.

Cleaning up permissions ran on the same mechanics: an exception with a justification grows back, an exception with a date does not. And with a feature nobody needs any more, an announced shutdown on a date is something else entirely from the same shutdown without the announcement, although technically nothing separates them.

So anyone trying to get a modernization through spends less time justifying it and more time dating it.

What nobody checks does not hold

The sentence that appeared most often across the articles, in contexts that have nothing to do with each other.

The tenant separation that is a claim after three months because no test pins it down. The four-statement rule for new caches, forgotten in two weeks without a place that enforces it. The handover that consists of a presentation without the one test. The brief to an agent whose boundary moves along with the work as soon as the agent may change the tests.

The conclusion is uncomfortable for documents and comfortable for developers: a rule is worth as much as the mechanism that checks it. Without one it is a statement of intent, and statements of intent hold until the next tight week.

Cutting smaller is almost always the answer

In the articles about attempts that failed, the cause was remarkably often the same, and it was never the tool.

Rector across the whole project instead of one directory. Observability everywhere instead of along one path. The replacement in one step instead of a series of blocks with a result each. The permissions all at once instead of starting with what demonstrably was never used.

The pattern behind it is always the same: the amount per step decides whether a fault can be attributed. Keep it small and every deviation is explainable. Make it large and every deviation is an investigation, and after two days everything gets thrown away.

What comes out of that is not slowness but the opposite. Twelve weeks in six blocks with a result each deliver something usable earlier than twelve weeks in one piece, and they survive an interruption.

Taking away is modernization

The fifth sentence was the one that surprised me most while writing, because it showed up in articles that were not supposed to be about it.

The cache with a two percent hit rate gets removed, not documented. Two services always deployed together are one and belong merged. The feature nobody has called in four years costs in every upgrade and every migration. The old path after a replacement belongs in the same task as the switch-over, not in a follow-up ticket.

Every one of those decisions makes the system smaller, and none of them can be presented as progress. Which is exactly why they do not happen on their own: the risk is distributed one-sidedly, and whoever takes something away has their name on the decision. It takes a procedure that can carry that, and it consists of measuring, announcing, switching off, waiting.

Two assessments that shifted while writing

Writing forty-four articles on one subject shifts a few assessments, and two of them belong here.

The organizational topics are not the garnish. I had planned the series technically and put the articles about ownership, handover, dates and scope in between as light relief. While writing it turned out that the technical articles regularly ended at an organizational question: who decides, who checks, who gets the alert. The code was rarely the bottleneck.

The difference between tools and procedures grew. Writing about Rector and about coding agents on the same subject made it clear that the interesting question is never "which tool" but "what checks the result". A deterministic tool needs a sample per rule. A non-deterministic one needs a net. The tools are interchangeable, the question is not.

Four entry points if you have a concrete problem

The series is not meant to be read through. Arriving here with a particular situation, you are best off starting at one of these four places.

The system needs rebuilding and nobody knows what it costs. Then it is about the five drivers of effort, the cut into blocks, and the second number missing from the conversation with management. The way in is What a modernization costs.

It runs, but every change is expensive. Then the order is: establish what is actually used, put a net around the place coming up next, and only then change something. The way in is Testing legacy code when there are no tests.

Operations are the problem, not the code. Then it is about delivery, observability, access and boundaries, and the cheapest single step is almost always deliverability. The way in is Blue/green and canary without Kubernetes.

Somebody is leaving, or somebody is arriving. Then it is about knowledge, access, and the one test that says whether a handover held. The way in is The handover day.

If you are facing a situation like that and are not sure where to start: write to me. Two sentences about the system are enough for an assessment of which of the four orders applies to you.

Every article in the series

The series runs in four alternating strands: existing systems and rebuilds, AWS and operations, backend and boundaries, and the topics that are not technology.

The series ends here, the subject does not. How I work on grown systems is described on its own page, and anyone who does not want to miss the next articles subscribes to the feed.