Start from scratch again
Why do we think it is better to rewrite all the code of a product?
Why do we think it is better to rewrite all the code of a product?
I think a lot of devs have the feeling that if they could start again a product, they will do it better because they will take the correct decisions. It’s some kind of arrogance in that way of thinking. Do we really know more than all the people that participated in the current system?
I think one of the more important reasons can make a company to take the decision of rewriting the code of one product is Accidental Complexity.
In fact Accidental Complexity is the final reason but what makes you to think in this way is the effects you see in your development team.
The team usually slows down a lot, the number of bugs is very high, and we are more time fixing things than working on features.
In this situation when the market change, we have a competitor, or we want to expand to another countries we only see a solution there. Start from scratch again and see if we do it better this time.
What means start from scratch?
In some sense start from scratch is like the last decision anyone wants to take, we are saying that we failed last time. In my experience, this problem happens when we create unmaintainable code. I’m not sure why we are so sure this time we will do it better, I think the Dunning-Krugger effect is very related.
There are several problems related to start from scratch that we have to take into consideration if we decide to follow this approach:
When to switch from one system to the other
How to migrate data
No knowledge on things we have in the old platform
If we write a system from scratch, we are selecting to change everything at once. This is a very risky approach and forces you to start comparing both systems to be sure your new system is not making you lose money. But if you compare both system with real users you will need to find a way to share data between them and this can be tricky, even can force you to use old databases (this limits you a lot in terms of new designs).
To compare both systems we could think on A/B testing but comparing complex systems means comparing a lot of variables, so we will not really understand why the new system is performing worse than the old one.
When this happens, we enter a rabbit hole. We usually think that this is happening because the new system needs to have the feature X the old system has. So we start to add more things to achieve the Feature parity.
Feature parity introduces more and more delays, if we are comparing both systems during a long time perhaps some people will ask to improve the old system, fixing some bugs or adding new features needed by the company. So we start a race where the new system cannot compete with the old one in terms of numbers.
In fact feature parity is a bad idea, we know that the use of features by users follow the Pareto’s principle, 80% of users only use 20% of application’s features. So if we are in this situation, it’s much efficient to identify the 20% of features that really interest to our clients and move them to the new system.
Another big problem with legacy system is that we don’t really understand some decisions made in the system and why these decisions were taken. In software architecture “The Why” is more important than “The How”, to avoid this happening again we can use ADR's.
How are we going to do it better this time?
I think we are usually tempted to introduce in the new project all the new fancy technologies, architectures we know, but we don’t change the way we work.
Many senior developers build the same types of applications year after year, and become bored with the monotony. Most developers would rather write a framework than use a framework to create something useful: Meta-work is more interesting than work. Work is boring, mundane, and repetitive, whereas building new stuff is exciting. This manifests in two ways. First, many senior developers start writing the infrastructure that other developers use, rather than using existing (often open source) software.
Building Evolutionary Architectures
We rely everything on tools but not in the process, Demmings said:
“95% of variation in the performance of a system is caused by the system itself; only 5% is caused by the people.”
W. Edwards Deming, Introduction to The Team Handbook
If we want to do it better this time we need to change our way of working, because that way of working result in rewriting the whole product. But what means to change?, in my experience this means to work with quality, Quality must be a first class citizen.
The final goal is not rewriting the application again, the final goal should be to change the organization to avoid rewriting again the app.
Is there an alternative?
I think there is a better alternative, to rewrite the whole product. But this is something also costly, basically is paying the Tech Debt the product has.
Start paying it completely but in different phases. Refactoring legacy code is difficult but sometimes cheaper than rewriting everything, it forces you to work in another way, to understand the product and to discuss if something is useful or not.
Sometimes we need to evolve the architecture. For example, if we want to introduce a new programming language we can create in our legacy system a bounded context with clear interactions with the rest of the system and later this is done. Move that code to another project with another language, then you can decide if this part is a microservice or how are you going to connect your old system with the new one.
There is something you will always need to refactor code, tests. If you want to know how to work with legacy code, I recommend you Working Effectively with Legacy code.


