"The universe likes nothing more than to transform that which was, into that which will be." - Marcus Aurelius
How did our code get so complicated?
Over time, many small well-intentioned changes pile up, they compound, and eventually bring on accidental complexity. Stuff that was once easy to do, becomes harder. The complexity tax kicks in and everything starts feeling like a heavy lift.
So, what can we do?
We've all heard that rewriting software is dangerous, that it wastes valuable time. "If it ain't broke don't fix it", right?
I'm here to tell you, I've rewritten software, and it made everything much better and easier to work with.
When done properly, a rewrite can free up a lot of energy that was lost to dealing with the complexity. It removes the complexity tax and makes the business's goals cheaper.
Sure, it's no silver bullet - nothing is - but over the course of building a system, we learn new things. These lessons need to be factored back in to the code, not just in incremental steps, but also by making their way back into the design.
To change? or to stay the same?
Basecamp was re-written 3 times. Yankee Stadium was rebuilt in 2008.
But many banks still run COBOL systems written in the 1960's.
So, who is right?
There is no hard and fast rule. Every situation is different. Everyone should analyze their specific situation and decide for themselves. Refactoring is enough in most cases.
And re-writing isn't a binary thing either. It's totally valid to re-write one part and refactor another. It's just another tool to have in the tool belt.
Re-write indicators
Here are some indicators that a rewrite is worth considering:
Have easy things become difficult?
There could be incorrect or missing abstractions. The abstractions may have once been correct, but wore down and no longer fit.Are upcoming changes costly?
If new features are on the horizon and they are expected to be difficult, it could be that a re-write will make that easier.When making changes, do they cause unexpected impact in unrelated places?
Dependencies between parts may not be clearly specified.Is production tracing relied on heavily to verify how things works?
The complexity may have gotten so out of hand, devs are having a hard time understanding it. So they rely on logs to understand how the system works. Re-writing can bring back clarity to the design.Can some changes only be accomplished by specific people?
There could be tribal knowledge or optimizations that are non-obvious. Re-writing can re-organize the abstractions and make them clearer, removing the need for tribal knowledge.Is more time spent on feature development or maintenance?
Constant maintenance can be thought of a design defect. It's a good idea to build features into the system to reduce maintenance.Do upgrades break things that used to work?
The system might need better verifiability. It could be missing automated tests, monitoring, or a paced rollout.
Refactor vs. Re-write
When should you use one over the other?
Both are methods of improving code. They are just on different sides of the "improvement scale".
Think of refactoring like renovating a house. Rewriting is like rebuilding the house.
Always prefer small renovations where possible, they're cheaper and less risky. But many renovation jobs might be more expensive than a rebuild.
For example, renovating a 2-bedroom home into an 8-unit residential building wouldn't make sense, because it needs a different type of foundation.
Ironically, it's usually the more important and successful stuff that is worth rebuilding, like the New York Yankees rebuilding Yankee Stadium in 2008. It's not that the old Yankee Stadium wasn't selling out - it was quite successful - that's what made it worth rebuilding.
Common arguments against re-writes
If it ain't broke, don't fix it.
Don't forget to consider the time spent on it. That may indicate that it is breaking from a cost perspective.
Won't re-writing waste valuable time?
Consider how much time is currently spent by not improving it?
Or, how much time could be saved if it was improved?
Why spend time on something that doesn't improve the business?
The goal of re-writing is to improve the business. By re-writing we are protecting a valuable asset, reducing labor, and freeing devs to work on other impactful things for customers.
After this re-write, what stops you from wanting another?
If a system warrants change then please re-write it again. As many times as it is valuable. Rewrite is just a synonym for improvement.
Customers don't care about code quality, they just want features.
The state of the code is the ability to ship new features. Customers may not know about code quality directly, but indirectly it impacts them a lot.
Our customers want a stable system.
Re-writing can be done while maintaining stability.
This system took years to build, won't it take years to rewrite?
It shouldn't, when done correctly. Rewriting is about compacting existing code and decisions into something simpler. It doesn't mean re-visiting past decisions.
The people that wrote this aren't here anymore, won't their knowledge be lost?
If their knowledge isn't codified in the system, in its documentation, or in its tests, then technically it's already been lost.
When to avoid the rewrite
- When refactoring will do the job.
- When the system is humming along without any problems.
- When the people doing the rewrite aren't experienced yet. It's best to avoid rewriting a system before deeply understanding how it works. See: Chesterton's Fence
- When it's just to use a different stack.
- When the system isn't important. It's probably not worth investing the energy. Better to find something else that is important and improve that.
- When there isn't a culture that values continuous improvement. If so, cultivate that first.
Summary
Ironically, when we try to stabilize a code-base by avoiding change, we increase the cost of changes, fear of change sets in, and it can end up hurting the resiliency of the system.
Incremental change is great, but it's not enough. The lessons we've learned over time need to make their way back into the design.
Re-writing is a great way for systems to remain relevant and keep costs down.
Don't believe the negative press it gets, it can save companies a lot of money.