Legacy Complexity Is a Premium Nobody Wrote Down
This series keeps making the same move. Write the decision down. Enforce the boundary. Don't multiply the units you have to govern. Put isolation in the index. Encode the judgment. Place the authority where the context already lives. Six posts, one instinct: take a guarantee out of a person's head and build it into something that holds without them.
Underneath all of it sits a question I have been answering by instinct for years and never once priced.
Every one of those moves is an investment. A feature flag. An expand-then-contract migration. A deduplication key. A tenant-partitioned index. Each of them buys the same thing: the ability to be wrong and still get back. And each of them costs something to design, build, carry, and eventually remove.
Someone who spends his working life on IT cost for CIOs put the question to me in the form that actually matters. How much should we be willing to spend to make more of our mistakes reversible? Clearly more than zero. But how far?
That is a good question, and "it depends" is not an answer.
You are not buying optionality, you are buying insurance
The framing that unlocked this for me is that reversibility is not a virtue. It is a policy against being wrong.
Which means it prices like one. A premium is only rational against the damage it covers. Nobody insures a kettle. Everyone insures a house. What you should be willing to spend on keeping a decision reversible tracks two things and nothing else: how expensive it is to be wrong, and how likely it is that you are.
That gives a shape immediately. Heavy investment on the few decisions where being wrong is both expensive and plausible. Close to nothing on the many where it is cheap or where you are almost certainly right.
And it names the waste, which is not the thing most teams worry about. The waste is not underspending on safety. It is paying the same premium everywhere. The team that puts a feature flag on every change is buying insurance against risks that do not exist, and the cost is not only the flags. It is the slower pipeline, the branching in the code, the accumulated toggles nobody dares delete. Worse, it teaches everyone that a flag is ceremony. So when a change comes along that genuinely needed one, it gets the same shrug as the other forty.
Uniform caution feels responsible. It is just an unexamined way of spending.
It is cheap at the seam and brutal afterwards
The second thing that makes reversibility economics strange is that the price changes depending on when you buy.
A feature flag put in before you ship costs close to nothing. Retrofitted into code that has assumed a single path for a year, it is a project. An expand-then-contract migration is nearly free if you plan the sequence up front, and archaeology if you already ran the destructive version and now need the old shape back.
So the skill is not making everything reversible. It is spotting early which decisions deserve it, while the joint is still open and the option is still cheap.
I have my own bill for this. I once chose a scheduler for a job that actually needed a queue. I have written about the failure itself elsewhere, but there is a second lesson in it that I missed at the time. That choice was cheap to make, and at the moment I made it, it was cheap to reverse. Almost nothing depended on it yet. By the time production told us the truth, months after development was called done, the job's state lived in two places that had quietly drifted apart, and reversing the choice meant changing the tool underneath the whole system.
The decision did not become more wrong over those months. It became more expensive to undo.
There is also a ceiling
The argument so far leans in one direction, so let me mark where it stops.
Past a certain point, keeping something reversible costs more than committing and living with the outcome. Optionality has a carrying cost, and over-optionality has a name you will recognise: two production environments running for two years because nobody will commit to switching off the old one. The migration that has been ninety per cent done since last spring. The abstraction layer that exists so you could swap the database you are never going to swap.
Some doors should be one-way on purpose. Deciding is the point of deciding. A choice you can always walk back is not really a decision, it is a deferral with a budget line attached.
The premium is not created at the decision, it accretes
Here is the part the standard advice misses, and it is the reason this piece exists.
The usual framing says: identify the one-way doors and slow down for those. That is good advice for doors that look one-way while you are standing in front of them. Some genuinely do. Deleting customer data. Signing a five-year contract. Publishing an external API.
But the decisions that have cost me the most were not like that at all. They were genuinely two-way when I made them. Nothing depended on the shared schema yet. Reversing it would have cost an afternoon and a mild apology.
It became a one-way door about six months later, and not because of anything I decided. Four other teams built on it, each making a perfectly reasonable local choice, none of them wrong, none of them consulting anyone, because from where they sat there was nothing to consult about. Nobody made a new architecture decision. The architecture changed anyway.
An architect I trade ideas with put a number on this better than I had. We save ten thousand today by making something harder to reverse, and nobody records the premium we just accepted. Five years later the constraint costs half a million to remove, and everyone calls it legacy complexity.
That gap is not a mispricing at the moment of the decision. That is the trap. The premium did not exist yet when I chose. It was manufactured afterwards, by every subsequent choice that assumed the hard-to-reverse thing would stay put. The coupling that turns ten thousand into five hundred thousand had not been created at the time anyone could have written it down, and no metric prices a dependency that does not exist yet.
Legacy complexity is mostly this. Not a catalogue of bad decisions, but a pile of reasonable ones whose reversal cost nobody was tracking.
Measurable at the margin
If part of it cannot be priced, it is worth being precise about which part can.
The operational half is visible at decision time, and it is readable off the change itself rather than judged in a meeting. Does this touch data you cannot recreate? Does it set a shape other people will build on, a schema, an interface, an event contract? Does it commit you to something outside the building, to a customer, a supplier, a regulator? Those questions have answers on the day, and they are the ones worth paying a premium against.
The accretion half is not visible, and pretending otherwise is how you end up with a scoring exercise that produces confident numbers about nothing.
But it is not invisible forever, and this is where I have found something usable. Technical coupling announces itself as callers, and a dependency graph will show you that much. What a dependency graph will never show you is that a supplier contract now assumes the current integration, or that an operations team has quietly reorganised itself around a workaround, or that the two people who understood the alternative have left.
Those costs live between functions, and every instrument we own points at one function. So the proxy I have come to trust is cruder and crosses all of them: how many people now have to say yes. When something you could once change inside a sprint now needs procurement, two other teams, and a slot in a steering meeting, the reversal cost has already moved. That is observable months before anyone could put a figure on it, and it does not require a new governance process to see. It requires noticing.
What to do about the half you cannot price
You cannot price the full premium at the moment you accept it. You can record that you accepted one.
"We chose this. We believe it is cheap to reverse, because nothing depends on it yet." That sentence takes ten seconds and it is not documentation for its own sake. It is a claim, and a claim is a thing the world can later contradict. Without it there is nothing to invalidate, which is precisely why the cost surfaces years on as an unattributable fact of life rather than as a decision someone made and someone else could have revisited.
Which finally answers the question of when to look again. Not on a calendar. Nothing happens on a decision's anniversary, and a scheduled review is a ritual a person has to remember to hold. The first one happens because it is new, the third slips a quarter, and then you are back where you started. Not on a raw dependency count either, because the number lies. Twenty consumers of a stable interface is nothing. Three that reached past the interface and built on its internals is the expensive case.
The trigger is the moment your reversibility claim stops being true. And the thing worth building is whatever notices that on your behalf.
The rule I'd leave you with
Every post in this series has taken a guarantee out of somebody's head and put it somewhere it holds without them. This one is about what that costs and when to pay.
Spend where being wrong is both expensive and plausible, and spend almost nothing everywhere else, because uniform caution is just waste wearing a serious expression. Spend early, while the joint is still open, because the same protection costs a hundred times more once the thing has set. Stop before optionality turns into a way of never deciding.
And when you do accept a premium, write down once why you thought this one would be cheap to undo. Not for the audit trail. For whoever finds out, possibly you, three years from now, that it stopped being true, and cannot tell whether anybody ever knew.
Which leaves the question I would actually want answered about your own system. Of all the decisions you currently describe as reversible, how many would still be reversible if you tried this quarter?