Monolith vs Micro-services & Upgrade Codebase vs Start Fresh – A Migration Story
They are always BIG decisions. The point where your web-application has reached a stage that it seems better to start fresh, but how do you know if it’s worth it? And whether or not you start fresh, how can you organize the roll-out? Are your reasons for upgrading or starting fresh the right ones?
Doing it Wrong: An Educational Story
Once upon a time, many years ago, I worked as a newly minted lead developer and started with a cool new project with my team. We worked hard, developing quickly and thought with the CTO together what features to build next. It was quite a complex application that aspired to move an older, stand-alone back-office application into the cloud, while also expanding into new markets. As the work progressed, the complexity grew. Customers came into the platform with custom wishes and it didn’t take that long for the system to feel like it hung together on silken threads.
By now I know this is very common for unstructured start-ups. By trying to find those early customers, often the business accedes to their demands for custom functionality. For this business this is great, as part of the development is paid by the customers, but eventually all this extra complexity that ends up being used by just a few, or sometimes nobody at all, starts to take it toll on the complexity and maintainability of the code.
We tried to separate things the right way, using separate “bundles” (as Symfony then called them then) to separate the different applications we wove together. Juniors came in and joined us on different new parts that we didn’t really have time (or incentive) to check up on. I have learned better by now – do NOT let juniors roam freely in an existing application.. instead work as a team and have seniors pair up with juniors to raise their standards and get a higher quality together.
That being said as a lead developer I was green too and didn’t have great examples either in the past or from my CTO to help me at that point. I fought to implement things like automated testing and continuous integration when it was all still pretty new and convinced my CTO and went ahead. Unfortunately this only slowed the development down further, as we were all new at writing tests and the total execution time of tests quickly became more than 30 minutes.
So there came a point in time when we had learned a lot and decided the current application had become a monstrosity with slow performance, slow tests, too much functionality that nobody used and was running on outdated versions and very manual deployment. Everybody agreed we needed to invest some time to improve our foundation, otherwise problems would get even worse and we would slow down even more in our development.
High Costs, Little Reward?
Of course building a new application, which seemed like a great idea to us developers, is a high cost. Understandably management wanted to know what exactly they were investing in and our CTO wanted to think with us how to minimize costs and/or do this in phases, so they could get a feel for the actual results.
I also have to admit that from previous experiences, working on old projects and always somehow managing, I wasn’t the most eager to start fresh. In the end it was sort of my baby and I wasn’t all that sure starting fresh would really be worth it. It is however different to work on old projects as a freelancer for a couple of hours a month, then it is to work with a team on an application that requires constant development and support. If we would be able to improve our development speed and effectiveness with new software by a factor two, you could calculate when this investment would earn itself back.
But there’s no clear numbers. You have no idea how much time it will take to build it back. You have no idea how much faster you will get with a better foundation. We kept arguing and spent a couple of tries on analyzing the system and it’s data model to come up with better alternatives and finding other reasons why this was the best approach.
Micro-services to Save The Day?
At some point micro-services came into the picture. An intern had written his thesis about this and we discussed how micro-services would be able to slowly migrate the application to a new form, while keeping the old parts in place. The lack of fairly fast results (building the whole thing anew would take a lot of time) was a main deterrent in making a decision. Especially my CTO saw great benefits of slowly migrating and testing the waters and the results that way.
I researched this on my own, what would micro-services bring from a technical point of view?
- They would separate functionality, forcing developers to properly decoupling code. Of course you can learn to decouple code without micro-services, which is probably easier too, but then it’s quite easy for a developer to stray and ‘hack’ his solution with a direct connection.
- They would make it easier to upgrade apps individually from each other, making it theoretically less likely to break the whole system.. of course this can still happen if the services depend on each other and may be even harder to debug.
- It would of course be easier to create a single part of the system anew and connect it to the old system, rather than first building the whole thing new. This way you could use the new features of new Symfony versions and play around with them, while the main application did not need to be upgraded yet. But then again, would the upgrade of the Symfony version be so hard it merits to use micro-services as an excuse?
- Micro-services could use a different language and/or database architecture. But then again, that was never really a problem and not the reason for us to use them.
I was in doubt. Were micro-services really the thing for us? Eventually I found an article saying that if you’re going to use micro-services, you should probably have at least as many developers as you have micro-services, to ensure they are each maintained well enough, because each may work a bit different. By that time I was already doubting because of all the extra complexity that we needed: a central authentication layer and logging layer, just to name a few. The argument on the number of developers made me stop and count. We were thinking about 6 micro-services, still not really going micro, but we had only 4 developers. I abandoned the idea.
Is it Worth To Upgrade?
Now you have to understand every application is different. More recently we took over an application that was built in Laravel and Angular with an offline-first approach that wasn’t implemented properly. Even though it’s not a very complex application, the code is very complex and that causes all kinds of problems. On top of that it’s built by juniors who didn’t really no how to code Angular and is completely lacking in automated tests. Working with that application a bit and seeing how long the developers are taking to solve some of the more urgent bugs was reason enough for me to convince the owner that we need to built a fresh version of this application. He easily agreed.
Continuing the above story, it wasn’t all that clear if we should still built a new application or simply upgrade the old one. Actually we went down the micro-service rabbit-hole thinking we would start fresh and use micro-services as a solution to do it efficiently. But now the micro-services were abandoned, should we then built a new monolith?
I argued we should, and should use a more LEAN approach to find out what customers really wanted. By then the company was starting to get some modest earning from the new application, but only from certain parts of the whole. Some parts were getting no traction at all. Unfortunately I was not really involved in the management decisions. I believe companies should involve the developers more in thinking about what features will actually make customers happy and drive revenue, but alas, this was not the case here.
Even though the CTO agreed we should probably make a new version at some point, there was never enough budget, so eventually I took matters into my own hand and decided to spent time on upgrading instead. I’ve learned over the years that much of keeping the application up-to-date, refactoring and updating coding standards is in the hands of the developers. It’s not something management, or even the CTO, is really thinking about. They are not working with the code on a daily basis and don’t really care what it looks like – as long as it works.
And unfortunately many developers don’t take enough time and initiative to both keep learning and beg time for such upgrade projects. It seems daunting to many developers to upgrade such a large application to a new version of the framework. I also had colleagues that were downright scared, as they feared it would break a lot of existing functionality. Monitoring was still in bad shape back then and we didn’t have full coverage on automated tests.
Still I forged ahead and upgraded the framework. I don’t think it took me more than two days. In retrospect I should have done it much earlier and much more often, which would have been even easier. I think it’s all in the mindset of developers to be either scared of these upgrades or do them regularly to avoid bigger problems. Also I’ve learned it helps a lot to have proper test coverage and monitoring to help track new bugs easily. Of course that goes way beyond upgrading and is always best to have.
The Final Problem Of Upgrading Or Starting Fresh
So in the end we upgraded, but it didn’t end at upgrading the framework versions. We rewrote much of the old code in a more modern and decoupled way and improved upon simple CRUDs by making fancy wizards and more user-friendly screens. In effect we did the same we would have done had we started fresh. I don’t regret doing it in the old codebase rather than starting fresh. In general I think programmers want to start fresh too easily. Of course in this case we already used Symfony and I still like it to this day. We just needed to keep up with the times and use the new features of new Symfony and PHP versions.
A happy ending? Yes, although I do want to highlight one important thing I’ve learned since. You only upgrade to the standards you have at that moment. When we upgraded this application, we did not upgrade the automated tests. We did not create a better pipeline. We also built new software in the same time and had the same problems there. All of our applications had problems with being tightly coupled, not being updated and suffering from junior developer influences.
That is why I want to highlight the final problem in upgrading or starting anew. If you don’t upgrade your standards, the benefits will be much lower than you might expect. High standards for your development team are in my eyes one of the most under-appreciated values you can instill. If your developers don’t upgrade their skill level from when you hired them, you are quickly getting outdated, which will cost you in outdated software with security, technical debt and maintenance problems.
How to solve the problem of degrading standards?
Find expert help! Great developers may be scarce when hiring, but there are some good developers turned freelancer or agency that pride themselves on keeping up with the times. With Solid Web Code it is our mission to raise the standards of web-development. We love to help you too.
Let’s start by finding out where you are today with our simple, but powerful scorecard: