Modernizing legacy systems
Technical debt is one of those funny things that can easily be ignored... until it can't, and you find yourself Googling articles on modernizing legacy systems.
One day, your legacy system is humming along on your in-house server, like it has for the past 12 years. The next minute, the world is on fire, and you're weighing up the options for bringing your dark ages legacy system into the 21st century.
There are several different directions you can go at this point:
- Salvage the code (if it's possible), update your dependencies, migrate to a new environment
- Replace the application with something off-the-shelf
- Rebuild the application with modern frameworks and technologies
There are probably plenty of situations where moving to a new environment or addressing problems in the existing app will get you over the line. But that content isn't exciting and edgy!
In this article, we're going to focus on rebuilding your application with modern technologies and truly future-proofing. We'll also briefly cover the "textbook" approaches to this problem, even though we think that only a couple are practical.
Before we get started, please hear out our quick pitch. You're looking for options to get your system up to modern standards so it's quick and reliable. We specialise in helping teams in your position. Drop us a line to see if we can help lighten your load. The worst that can happen is that you get free experience-backed advice!
The problem with your outdated software
Outdated software starts to accumulate a unique set of risks:
- Software dependencies and underlying packages are no longer supported, so if there's a problem, you're stuck
- Developers typically learn and practice modern software, so it can be difficult to find qualified help
- Legacy software becomes less cost-effective over time as high maintenance costs for the reasons I just mentioned
- For legacy systems that are running on in-house infrastructure; there's always a risk that the hardware fails, ending up with long down times
Modernizing legacy systems is all about risk mitigation. Can your business bear the cost of your existing systems going offline for a week? Or even if your system is perfectly hardened, can it adapt to whatever changes your business is going through?
The next logical question is whether the cost of bringing your system up to modern standards will ever pay for itself with future growth. There's no straight answer to that question, but cloud infrastructure is pretty awesome these days.
With the rise of serverless databases, headless API-driven solutions, and affordable distribution through global content distribution networks, ongoing costs can be significantly cheaper for a modernized system, especially one that needs to scale.
How much will my modernization project cost?
There's only one way to answer that question, and that's going through a full Product Roadmapping process.
I don't want to bore you by rehashing the topic since I've already covered a bit of it above. The basic idea is that every feature of your system is documented through user stories, and those stories are estimated by our project team.
The Product Roadmapping process is priced separately to the project so we have no incentive to rush through it or to overprice the main project. At the end of the process, you get a water-tight plan for the modernization of your application, along with a detailed breakdown of costs and timeframes.
Where to start your modernization project?
Planning and documentation are always the place to start, but it also depends on where you're at in the process. This is a summary of everything from start to finish:
- Documentation
- Architecture plan
- Build & write tests
- Migrate data
- Set up your new environment
Arguably the toughest part of the entire exercise is capturing the system requirements and writing the documentation. Once that's done it's not like the rest of the process is "easy", but it's mechanical.
Documentation: Is it even possible to rebuild this undocumented system?
Yes, but there's no shortcut. There are two approaches you can take:
- Work through the codebase and document each function
- Go through a Product Roadmapping process
Working through the codebase line by line is no fun, especially if you don't have someone with intimate knowledge of the application. Given you're working with a "legacy" system, chances are not everyone who was involved in writing the application is around to help answer questions.
This problem is compounded if the application is written in some archaic language like Visual Basic Applications (VBA) that takes forever for modern developers to read, let alone understand.
The other option is jumping straight into a Product Roadmap. We've written a pretty detailed guide on how Product Roadmaps work so we won't go too deep. The idea is to capture the user workflows, then break them apart into user stories and finally into individual features.
The risk of building a Product Roadmap for a legacy system is missing an important feature that's hidden somewhere in the existing code.
The winning formula usually lies somewhere in the middle. Start with a Product Roadmap to lay the business goals and foundations. The team responsible for the legacy system modernization process needs a document to reference that explains the business logic behind each of the application's features. Once the document is ready, the project team can attempt to read and document the codebase. If they get stuck, there's at least a document they can reference to understand what in the world the application is trying to do for the user.
It's a difficult and challenging task, but our team have experience and know the challenges well. If you're reading this article in hope of finding a team to handle this job for you, drop us a line. At the very least you'll get some experience-backed advice on how to move forward on your legacy modernization project.
The Architecture Plan - Picking your tech stack
Once you've built your Product Roadmap, it's time to figure out what technology you're committing to.
The choice is often an extension of whatever your legacy system was built with. For instance, PHP has been around a looooong time. If your legacy system was built on an ancient version of PHP then it'll make sense to keep it running on PHP, and migrate the functions into a framework like Laravel.
In cases where your application has been built in a technology that's no longer popular, or isn't suited to running in the cloud, then it's time to pick modern systems.
Everyone has an opinion on which language is the best. Stackoverflow captures the most popular languages and frameworks each year in their developer survey. These are the results from front and backend frameworks in 2022:
I've annotated what kind of language each of the top results is (frontend, backend) and which language it's built on top of. JavaScript dominates the top of the table, which is no surprise since it can do everything. Between frontend frameworks like React, Vue and Angular, and runtimes like Node and the frameworks it supports, plenty of enterprise applications are built on top of nothing but JavaScript.
The point we're making here is that JavaScript is a safe choice, and one we would recommend. Our team built a lot of Laravel (PHP) backends, and it's also a great choice.
However! If a new client asked us tomorrow what architecture we would recommend for their application, without knowing their requirements, our suggestion would be:
Next.js + tRPC + Tailwind CSS + TypeScript + Prisma + NextAuth.js
This stack is called T3 and it was made by the CEO of Ping.gg. It's bleeding edge stuff and focuses on performance, modularity and full-stack typesafety. The stack hinges on Next.js, which is a React-based framework that's been extended for developing full-stack applications with the help of the supporting technologies.
If you're unsure what architecture will best suit your legacy system modernization approach, drop our team a line, and we'll help you think through the options.
Build and write tests
The next step is getting your hands dirty and rebuilding the application.
If you're optimizing existing code, this will be a challenge of porting parts of the application over bit by bit, updating them to work with the technology's dependencies before moving on to the next step.
If you're rewriting your application from the ground up, it's more likely to be a series of sprints where your development team aims to build a set of features every couple of weeks. By this point, you should have already committed to rebuilding your tool internally or hiring a development team, and if they're worth their salt, they'll follow a viable methodology to get the application built and tested correctly.
Write automated tests for your features. Going through the effort to modernize your system with new and better capabilities only for it to become unstable and not work as well as the previous version is nobody's idea of a fun time.
Achieving good test coverage has a huge suite of benefits to the bottom line. It takes time and arguably slows the pace of the project down since the team have to think through all the potential side effects of each feature. However, automated testing heavily reduces the amount of rework and implementation time for new features in the future.
Migrate your data
Data migrations are often tricky, especially if your team has had to change the schema along the way to accommodate upgrades and changes to technology architecture or functionality. If your legacy system is a few years old, you could have to accommodate a significant amount of data. There's a chance there will be problems, inconsistencies, or junk data in outdated systems you'll need to work through.
There's not a lot of concrete advice we can give you on migrating your data, except that you'll want to make a plan early on and account for the process taking a while.
Picking the right database
One thing that's going to make life difficult with data migration is picking the wrong kind of database. Your team should work this out pretty quickly, but if you're moving from a relational database like MySQL to a Document database like MongoDB, then you're going to have a bad time.
Why would anyone do this, you ask? Well, the MERN (Mongo, Express, React + Node) stack has been pretty trendy for a little while. JavaScript devs love it because they can manage a full-stack app without having to jump between languages. For most applications, this stack is going to cause inflexibility.
We've written a guide on picking the best database for your project you should check out before making this architectural decision.
Set up your new environment
If your legacy application has been running on a server managed by your business, or even by a small infrastructure company, then you're in for a treat. Cloud computing and managed infrastructure have come a long way over the past five years.
Cloud hosting has been delineated into different products:
- Virtual private servers
- Routing and load balancing
- Content distribution network
- Middleware services
- Firewalls
- Managed databases
Pretty much anything your legacy application had, you can get in a dedicated cloud form. The benefit to being able to pick and choose which pieces make up your new environment is unlocking scaling performance and cost efficiencies you can't otherwise.
For example, if you only need a load balancer for a certain part of the year, there's nothing stopping you from spinning it up and down when required. It's a similar story for resources. Need extra processing power and memory for a month or two? Just ramp your VPS up and down as required.
Lots of businesses gravitate towards Amazon Web Servers for their infrastructure needs. To be honest, AWS is pretty great, but Amazon does everything in their own non-standard way which is kind of a pain in the ass for the uninitiated. We're bigger fans of DigitalOcean and Cloudflare. Between these two services, most of your environment requirements will be covered.
Things to look forward to post upgrade
The process of bringing your legacy systems up to date can be gruelling, costly and time-consuming but just think about what life will be like on the other side.
The headaches that you have put up with in the old system can finally be ironed out, without the risk of everything going offline. Those workarounds your team have become used to can be thrown in the trash. Maybe you can even get to your system on your phone?
It's easy to grow comfortable with legacy systems and forget that the entire software world has undergone a user experience revolution over the past decade.
Wrapping up
There's a lot of decisions to make when figuring out how to modernize a legacy system. Do you try to update the existing codebase (if that's even possible) or start from scratch? Then there's the question of how to document your new system, what tech stack to use and what kind of infrastructure to commit to.
The best way to think through all these decisions is to create a Product Roadmap and spend a couple of days working through every possible question.
If you think we've missed anything, which is likely because it's a big topic, feel free to leave a comment below and we'll get back to you.