Is a legacy rewrite the right choice for you?
by John Browne, on Oct 30, 2023 2:56:24 PM
Since today is Halloween, I thought depicting legacy applications as sort of the living dead was on-brand. I mean, they work, right? Just maybe not great. At least they don't want to eat your brains.
Or do they?
I've spent years writing about why automated migration tools like VBUC or WebMAP beat a rewrite hands down. Frankly if you can't find the data and reasons to choose automated migration by browsing this website you probably never will. And for most of the customers I talk to, automated migration is a better answer than the alternatives.
But there are exceptions, and in this post I want to discuss when it might make more sense to start from scratch.
When to modernize?
I had a house once that needed a new roof. Now, to be clear, "needed" in this case was relative. From my point of view, the roof was fine, it covered the house, it was relatively clean looking (for an old roof), and most importantly it didn't leak. I knew it was older than the theoretical life expectancy of its material, but I didn't have any pressing problems from its age.
However, from the point of view of my homeowners insurance company, it was past its sell-by date. In order to renew the policy, I had to replace the roof. That moved the roof-modernization project from "important but not urgent" to "get 'er done" on the priority list.
Everyone in IT or software development knows that any application at least 10 years old is suffering from legacy issues in some way. Apps twice or three times that age are probably in pretty terrible shape, but just like zombies they neither die nor get better on their own.
Probably the most common scenario is some external forcing function that drives the project--like my roof--into "get 'er done" mode:
- ISVs with desktop apps get hammered by a new competitor with a SaaS offering; easier to keep current, more user choices, spiffier look and feel.
- Knowledgeable developers age out, retire, or are hard to replace. They just don't teach PowerBuilder, Clarion, or VB6 at university these days.
- OS update kills some functionality: Microsoft briefly tanked some old VB apps when they deprecated a TLS version; they heard the howls of despair and made an update. It could happen again anytime.
- Not-64 bitness: It's still possible to run 32-bit stuff on Windows 10 and 11, but really old 16-bit stuff died years ago and it's just a matter of time before 32-bit stuff will get clobbered. Old apps usually have old components long out of support and these will be the first to die.
When does a rewrite make sense?
While I'm not recanting my long-held belief that, in the majority of cases, automated migration beats a rewrite, there are situations where a rewrite does make more sense. Let's look at some:
Small sweet simple
These apps are super straightforward: the UI is basically some forms; the forms largely generate SQL in the middle tier, and the SQL gets some data from the database layer and sends it back to the client. The business logic is either largely non-existent or simple. The app hasn't been hacked to pieces over the years, but has been maintained and documented cleanly. And it's not terribly large: total lines of code are, say, under 50,000. It works fine, but you want to move to a language and framework that is a standard in your organization and no migration tools support that target.
Where these projects go well is a phased approach with a clean re-implementation of the existing functionality in the new language and framework, saving any real enhancements for a post-modernization project. It's always the scope creep that will kill you.
There are apps that are so old, so large, and so convoluted that literally no one left in the organization understands them anymore. Code buried deep that was written for DOS. All the original engineers long gone and no real documentation to speak of. The worst examples of this are the still extant applications written for mainframes in 360 Assembly. I'm not sure today's flock of CS graduates have ever even SEEN assembly, let alone tried to untangle and update some written when their parents were kids.
Regardless, even those written in the PC era can be a nightmare to migrate, with or without tools. Probably every dev who's worked on really old weird code has seen comments like "Never touch this" or "I don't know why this works but it just does."
One reasonable approach to replacing these zombies is to rethink the solution to the problem. Start by defining the business problems you need to solve and what functionality needs to be created to address them. Then design away based on your current favorite languages, architecture, and frameworks. Yes it will be painful, expensive, and time consuming. Managing the project to focus on delivering functionality quickly and avoid scope creep or shifting requirements will be critical. As well as a lot of luck.
I know better
Many of our customers use our engineering teams to do their migration for them, choosing to keep their own people focused on the work that is best suited to their skills and priorities. Just because we do the migration doesn't free the customer from any involvement, however, as--particularly with complex WebMAP migrations--lots of decisions have to be made and customer involvement is required.
Most of the time this works well for both parties: us and them. There are, however, signs that a joint project like this can run into trouble. Some of the mismatches include:
- Customer doesn't understand our migration process, which is horizontal rather than vertical.1 This can lead to a disconnect on how much actual progress has been made at a point in time.
- Customer isn't accustomed to working with an external engineering team. Subtle but distinct differences exist between projects with an in-house team and versus and external one. Some of the keys to success are clear lines of authority and accountability, structured, regular communication, and complete transparency on status, issues, and progress. Come to think of it, that's all pretty important with any team, regardless of where they are.
- Mismatched expectations: It's vital for any partnership like a large project where both parties are involved that expectations are aligned. We have a good process and track record for predicting in advance what the issues with a complex modernization project will be, but the future is uncertain and nothing can perfectly guarantee that unforeseen issues won't pop up. Were expectations on both ends clear about how those inevitable issues would be handled? Customers who listen carefully, ask clarifying questions, and acknowledge potential scenarios are more likely to get to the end of these projects contented.
The last word
Every application becomes legacy at some point. Everything wears out eventually, including software. Let reason--not emotions--inform when and how to deal with it. And just as not every legacy app should be rewritten, neither should all be migrated to a new platform. You want a migration? We have tools and people. You want a full-on rewrite? We have people and experience with that, too. Your call.1 Over the years, we've learned the most efficient way to tackle a migration is to take an issue and fix it across the entire code base before moving on to the next issue. This is a horizontal approach, if you will, compared to a more "traditional" approach of debugging an entire file or module before moving to the next one.