We’ve all been there: the codebase is a tangled mess, and working with it feels like walking through a fog. Years of development, patches, and bug fixes have led to an overwhelming technical debt. The idea of starting from scratch seems like a dream come true—a fresh start, a chance to do things right this time. You get excited about a new technology, a clean slate, and the promise of a better, more flexible future. But before you leap into a software rewrite, let’s take a moment to reflect on the hard-earned lessons from Kakbima’s own rewrite journey, where we migrated from a monolithic system to a microservice architecture.
The rewrite temptation: Starting fresh feels good—until reality sets in
When we decided to overhaul our platform at Kakbima, it was tempting to walk away from the complexity of our existing monolith. After all, our insurance management and distribution platform had become a behemoth—an intricate web of tightly coupled services that no longer served our evolving needs. We were convinced that starting over with a microservice-based architecture would fix everything. After all, microservices promised flexibility, scalability, and easier maintenance.
At first, the transition felt exhilarating. We thought we could just list out the features, build a roadmap, and be done with it. It seemed straightforward. But, as we’ve learned, the true cost of rewriting software is never what it seems. Here are the three key factors that turned our rewrite from a simple task into a massive undertaking.
1. Catch-up cost: Keeping the old system running while you build the new
One of the biggest surprises we encountered was the “catch-up cost.” If you’re replacing a useful software system—like we were with our monolithic platform—there’s no stopping its usage. Your customers still rely on it, and your support teams can’t just pause maintenance and bug fixes while you build something new.
At Kakbima, we found ourselves in a position where our new microservices-based platform couldn’t simply replace the old one overnight. As our development team worked tirelessly on the new system, the old platform was still churning out new features, fixing bugs, and keeping up with customer demands. We underestimated how much effort it would take to “catch up” to the old system while simultaneously building the new one.
For example, while the rewrite team focused on breaking down the monolithic codebase into microservices, the old system kept evolving. Customer requests, urgent patches, and additional integrations continued to pile up. The gap between what the new platform was capable of and what the old system could do kept widening. Even though our new team was working at full speed, it took much longer than expected to catch up to the original system’s capabilities.
We had to factor this catch-up time into our project estimates, and this alone added several months to the timeline. For instance, if the new team was working 1.5x faster than the old team, we had to account for that in the form of delayed features, unexpected development needs, and rework. What we originally estimated to be a one-year rewrite quickly turned into an 18-month project.
2. Undiscovered scope: The hidden complexity of legacy systems
Another challenge we faced was what we now call “undiscovered scope.” When you rewrite an old application, especially one that’s been around for years, there’s always the risk that you’ll miss hidden features or legacy quirks that customers depend on.
Our original system had accumulated years of technical debt, with countless bug fixes, patches, and unrecorded features that were deeply embedded in the product. Some of these features were forgotten, some were poorly documented, and some were simply taken for granted because they worked—until we started building the new version.
We didn’t realize how many little-known processes and workflows our customers had come to rely on. For example, our old system had custom workflows for handling insurance policy renewals that weren’t part of the original design, but they had been so heavily used by our customers that they were essential to their operations. These “hidden features” surfaced during the development of the new system, creating additional work and complexity.
This “undiscovered scope” added unforeseen development time. Even with our microservices architecture, we found ourselves having to revisit and rework certain aspects of the new system to accommodate these legacy features. A feature that seemed straightforward in the planning stages turned out to require significant adjustments and additional resources, especially as we uncovered dependencies we hadn’t anticipated.
3. Adoption enhancements: Why customers are reluctant to switch
Even when you’ve reached feature parity with your old system, the hardest hurdle is convincing customers to actually switch. This is something we underestimated at Kakbima.
Our legacy platform was deeply integrated into the workflows of many insurers, brokers, agents and customers. Over time, users had become experts in navigating its quirks and finding workarounds for its limitations. The old system, despite its flaws, had become a known quantity, and switching to something new was a risk many were unwilling to take.
So, after months of building out a feature-for-feature equivalent with our new platform, we still faced resistance from customers who weren’t sure if the new system would truly meet their needs.
For instance, while our new microservices-based platform had enhanced capabilities, such as automated claims processing and real-time policy updates, many customers were still unsure about how these features would fit into their existing processes. They didn’t want to give up the familiarity of the old system unless there was a clear, undeniable benefit.
This is where the “adoption enhancements” came into play. We had to go beyond simply replicating old features and deliver new, compelling reasons for customers to switch. For us, this meant adding new capabilities like an integrated insurance wallet, personalized product recommendations, and smoother cross-platform integrations. We also focused on making the transition as painless as possible, with automated data migration and training tools.
But these enhancements took time and resources, pushing our timeline further out. We had to account for this in our final cost estimate to ensure that the new system wasn’t just functionally equivalent to the old one, but also provided real value that would justify the switch.
Bringing it all together: The true cost of rewriting software
At the end of the day, we learned that the true cost of a software rewrite is far more than just the time it takes to rebuild the features. It’s the hidden costs of catching up with ongoing development, discovering unexpected scope, and making your product compelling enough for users to embrace the change.
Using the formula we devised at Kakbima, we can calculate the true cost of a software rewrite as follows:
True Cost = Initial Estimate (Test) + (Catch-Up Cost Factor * Test) + (Undiscovered Scope Factor * Test) + (Adoption Enhancements Factor * Test)
To illustrate, let’s assume our initial rewrite estimate was one year (Test = 1 year).
- If our new team was working 1.5x faster than the old team, we’d add 50% for catch-up time (Catch-Up Cost Factor = 1.5).
- If undiscovered scope turned out to be 20%, we’d add another 20% (Undiscovered Scope Factor = 0.2).
- Finally, if it took an additional 30% effort to make the product compelling enough for adoption (Adoption Enhancements Factor = 0.3), our total rewrite time would be 1 + 0.5 + 0.2 + 0.3 = 2 years.
In our case, the rewrite project that seemed simple on paper ended up taking twice as long as we initially estimated. But these lessons were invaluable. They taught us that a software rewrite isn’t just about rewriting code—it’s about managing the complexity, aligning with customer needs, and preparing for unforeseen challenges.
My takeaway
Before diving into a rewrite, take a hard look at the true costs. It’s rarely as simple as just building the new system and switching over. There’s a cost to catching up with ongoing requests, discovering hidden complexity, and ensuring your new system is enticing enough for users to make the switch. I’ll explore alternatives to the full rewrite approach in a future post. For now, remember that rewriting your software from scratch can be a massive, time-consuming undertaking, but with the right planning and strategy, it’s possible to build a more flexible and scalable system—without losing sight of the end user’s needs.