There is a phrase I have heard in almost every company I have joined with a mature product in hand: "this is so bad that it is best to rewrite the whole thing."

I have said it too. With total conviction. Looking at code that nobody dared to touch, with dependencies that seemed to hold by faith, and documentation that consisted of asking the only person who had been there for seven years.

When I joined Enterticket as CTO, I found myself in exactly that scenario: a legacy product that worked —it billed, had real customers, supported daily operations— but was extremely difficult to evolve. And, as expected, in one of the first meetings, someone put the nuclear option on the table: start from scratch.

It didn't take me long to realize that this was, almost always, the worst decision we could make.

The Trap of the Big Rewrite

The Big Rewrite is the favorite trap of the technical ego. And I say this without condescension, because I have fallen into it.

It is seductive for several reasons. It is more fun to build something new than to understand something old. It gives a sense of control: "this time we will do it right." And it allows you to avoid facing the uncomfortable part of engineering, which is living with the decisions —good and bad— that others made before you.

The problem is that rewriting a production system from scratch is betting the business on a single card. While you build the replacement, the world doesn't stop: the old system remains alive, still needs patches, and your competition keeps shipping new features that you can't match because your entire team is busy rebuilding what you already had.

Eighteen months later —if you get there— you launch a product that, in the best case, does the same thing as the previous one. Zero new value for the customer during all that time. And that is assuming the project finishes, which often doesn't happen.

What You Really Lose When You Rewrite

Beyond the timeline risk, there are three things that are lost and almost never appear in the initial estimate.

Business rules hidden in the code. That weird 'if' statement that looks like an error is, almost always, the scar of a real-world case: an important client, a legal exception, a bug that cost money. When you rewrite, those rules are not in any document. They are in the code you are going to throw away. And you rediscover them one by one, in production, usually when they break.

Momentum. A team that goes more than a year without delivering visible value wears out. Management gets impatient, sales reps have nothing new to talk about, and team morale erodes. The energy of building something new lasts three months; the rewrite lasts much longer.

Money, which is not a minor detail. Every month of rewriting is a cost without a return. You are not reducing technical debt incrementally: you are financing a promise.

The Alternative: Evolutionary Modernization

The good news is that there is a path that does not force you to choose between "enduring the legacy forever" and "burning it all down." It is called evolutionary modernization, and the idea is as old as it is sensible: change the system gradually, while it keeps running.

The classic pattern for this is the Strangler Fig. The name comes from a tree that grows around another until it completely replaces it, without there ever being a gap where a tree once was. Applied to software: you surround the old system, move one capability at a time to the new one, and turn off the old piece only when the new one fully covers it.

For this to work without polluting the new with the vices of the old, an anticorruption layer helps: a boundary that translates between both worlds and prevents legacy data models from leaking into the modern system. It's the difference between building next to the legacy and building inside it.

The real benefit? You deliver value from the very first week, distribute risk across dozens of small steps instead of concentrating it in a single big bang, and preserve business knowledge as you transfer it, rather than losing it all at once.

How to Approach It in Practice

Order matters more than speed. This is what has worked for me.

  • 1. Measure what actually hurts. Don't rewrite what works just because it's ugly. Identify which parts of the system concentrate bugs, delays, and complaints. That's where your return is; the rest can wait for years without a problem.
  • 2. Isolate before you touch. Put a clear boundary between the old and the new. An anticorruption layer, a stable API, whatever it takes. You need to be able to change one piece without shaking the entire building.
  • 3. Start with high pain and low risk. The first migration must be a visible success. Choose something that matters to the business but, if it goes wrong, won't halt operations. That first victory buys you the confidence for the difficult ones.
  • 4. Turn off the old only when the new covers it. The legacy is not deleted the day you launch the replacement. It is deleted the day you have been in production for weeks without incidents and nobody misses it. Keeping both versions for a while is not indecision: it is prudence.

And When Does It Make Sense to Rewrite?

It would be dishonest to sell you the idea that a rewrite is never the answer. Sometimes it is.

When the base technology is truly dead —without support, without people who know it, without an upgrade path—, patching is throwing money away. When the business domain has changed so much that the original model no longer represents reality, dragging it along costs more than rebuilding it. And when the system is small and self-contained, rewriting can be a matter of weeks, not years: there, the risk is acceptable.

The key is for that decision to be a reasoned conclusion based on cost and risk, not an impulse born from the frustration of reading someone else's code. Rewriting because the numbers justify it is strategy. Rewriting because "it's too much effort to understand it" is ego with a budget.

The Question That Really Matters

After fifteen years of doing this, I have reached a simple conclusion: architecture is at the service of the business, not the other way around.

Modernizing is not about chasing technical elegance or having the cool stack of the year. It's about reducing the cost of changing tomorrow without failing to deliver today. If a modernization doesn't make your team faster and your product easier to evolve, it's not modernization: it's redecorating.

That is, by the way, one of the things I value most when I accompany teams at Venturest: the right decision is almost never the most spectacular one. It is the one that keeps the business running while making it more capable from within. No lock-in, no stopping delivery, and leaving the team stronger than before.

So, before approving that plan of "let's rewrite everything," it is worth asking a single question:

Is your team modernizing... or are they rewriting and praying?

Paulo Bischof
Paulo Bischof
CTO · Product Manager · Software Developer
Vamos conversar