If It Ain’t Broke… Should You Still Fix It?
One of the most tempting decisions in engineering is to rewrite a system from scratch.
Every engineer eventually encounters a codebase that feels frustrating. The architecture may be dated, documentation may be thin, and even small changes can require navigating layers of complexity that have built up over years. At that moment, a rewrite can feel like the obvious solution. Starting fresh offers the chance to design the system differently, use modern tools, and correct mistakes that may have accumulated over time.
But experienced engineers know the decision is rarely that simple.
A working system contains far more than just code. It contains years of edge cases, production lessons, operational knowledge, and incremental fixes that were often discovered the hard way. Much of this knowledge is rarely documented because it lives inside the system itself.
When a system is rewritten, much of that experience disappears with it.
New systems often appear cleaner because they have not yet accumulated the same complexity as the one they replace. But that complexity rarely appears by accident. It often exists because the system had to solve real problems such as unusual traffic patterns, integration quirks, or operational constraints discovered over time.
A rewrite must eventually rediscover many of those same problems. Until it does, the new system can actually be less stable than the one it replaced.
This does not mean systems should never be rewritten. Sometimes the underlying technology is no longer supported, or the architecture fundamentally prevents the system from evolving. In those situations, a rewrite may be the right decision.
However, many successful systems survive because they are improved gradually rather than replaced entirely. Small refactors, targeted modernization, and incremental architectural changes allow a system to evolve while preserving the operational knowledge embedded within it.
“If it isn’t broken, don’t fix it” is advice that has existed long before modern software development. Like most guidance in engineering, it is only partially true.
Systems should evolve as technology improves and requirements change. At the same time, stability has real value.
The real skill lies in recognizing when a system truly needs to change and when it simply needs thoughtful improvement over time. That balance is where engineering judgment matters most.