Old code is easy to criticize.
Messy.
Outdated.
Hard to work with.
But it keeps running.
Not by accident.
Because replacing it is harder than keeping it.
Old code is not just code — it’s accumulated behavior
Every system starts simple.
Then it grows.
- bugs are fixed
- edge cases are handled
- workarounds are added
Over time, the system becomes a record of everything that ever went wrong.
That’s why replacing it is difficult:
you’re not replacing logic —
you’re replacing history.
Rewriting loses what you don’t understand
A rewrite starts from a clean state.
But the original system is not clean.
It contains behavior that was never documented.
As described in Why Software Rarely Gets Rewritten From Scratch:
rewriting removes not just problems,
but also solutions you didn’t know existed.
Rewrites often introduce regressions because stable systems “get more stable with time” and accumulate fixes .
Migration doesn’t solve the problem — it spreads it
If rewriting is too risky, teams try migration.
Move parts of the system gradually.
But as described in Migration Projects That Never Finish:
old and new systems start coexisting.
Which means:
the old system doesn’t disappear.
It becomes part of the new one.
No one fully understands what they’re replacing
Modern systems are too complex to fully map.
Knowledge is incomplete.
Distributed.
Often outdated.
As explained in The Systems Nobody Fully Understands Anymore:
you don’t fully understand the system you’re trying to replace.
And you can’t safely replace what you don’t understand.
This is a common issue in legacy systems where knowledge and documentation are limited or lost over time .
Systems evolve in ways that were never planned
Over time, systems drift.
Configurations change.
Dependencies shift.
Behavior adapts.
This is exactly what’s described in Configuration Drift: The Silent Killer of Infrastructure.
The system you see today
is not the system that was designed.
It’s what survived.
Dependence protects old code
Old code doesn’t survive because it’s good.
It survives because it’s critical.
As described in When Daily Life Depends on Software Infrastructure:
systems become infrastructure.
And infrastructure is hard to replace.
Not because of code quality.
Because everything depends on it.
Stability becomes a feature
Old systems may look inefficient.
But they have something new systems don’t:
proven stability.
Replacing them means risking that stability.
And stability is often undervalued until it’s gone .
New code doesn’t start where old code ended
A new system doesn’t inherit maturity.
It starts from zero.
Which means:
- missing edge cases
- untested scenarios
- unknown failures
Old systems didn’t avoid these problems.
They survived them.
What this actually means
Old code survives for a reason.
Not because it’s loved.
But because it’s difficult to replace safely.
Old code is not the problem.
It’s the result of everything the system has learned.
And replacing it means
giving up that knowledge
without fully knowing what you’re losing.