Taming the legacy beast — part 2

CrafterOfSystems
4 min readApr 24, 2024

--

This is part of the article series about taming the legacy beast, read part 1 here.

We have (almost) all been there, working with the old legacy system created 10–30 years ago. The old monolithic design is causing so many challenges for the development team.

  • Keeping up to date with third party dependencies — whenever there are breaking changes you need to update it everywhere at the same time. not to mention when a dependency is used by another dependency, you can easily get into a never ending story causing you to give up on the update.
  • Application servers — when your code is served by application servers, you might run into the problem that a server you are using is discontinued or suddenly becomes much more expensive so that you cannot upgrade. You will be stuck on a particular language/framework level until you take the hassle to replace the server with an alternative
  • Framework updates — since your code is monolithic, you need to upgrade all at once, a daunting task , especially if the new version requires a new language version and maybe you also need to update the application server(s). When functionality you use in the framework is deprecated or discontinued, you are in for a real challenge
  • Language updates — same challenges as for framework updates
  • Legacy UI framework — your UI is written in a legacy framework like JSP or ASP, or maybe just plain HTML. You want to start to use a modern framework like Vue, React or Angular. Your UI is quite large and complex, including a lot of logic in both JavaScript and in the backend.
  • Data model — you have an old, normalized data model with lots of relations and constraints. It is very difficult to make changes, it has started to affect performance, especially if you do both OLTP and OLAP in the same database.

In this article series we will tame an imaginary legacy monolithic enterprise application, known as The System. In each part we will address a specific part of the system. I hope this will be an inspiration to you how to address your own legacy beast, to get started on the path to the future. Since each system has its own challenges, the order in which you address the challenges will vary. Once again, The System is imaginary, I have never worked with a system in quite this sorry state. It is exaggerated in order to be the greatest candidate possible for refactoring .

Overview of The System, legacy version

The System is a monolith made up of a number of sub-components in different state of entanglement, each having a specific purpose, but the years have not been good to code structure. All sub-components are in the same repository, all sharing the same dependencies, language level, framework versions etc. The monolith implements all the functions for serving data to clients, it has logic being triggered by external events or schedulers. The business logic in the monolith interacts with the outside world through its sub-components:

  • event export — external systems are interested in what is going on, the business logic continuously sends events asynchronously to the event exporter sub-module, which in turn filters and transforms events to be sent to the outside world using different methods (web hooks, file exports, queue integrations)
  • clients — The System has a web UI served by the portal server, the portal server using synchronous communication to the business logic to fetch data and perform actions. The app api sub-module exports a REST interface used by mobile applications.
  • data importer — The System needs some data to apply its business logic upon — the responsibility of the data import sub-moduleis to get data from external sources and add it to the database.
  • 3rd party integration — there are a number of external services used by the business logic to get additional data or send out requests and information as part of the functionality. The communication between the business logic and the external 3rd party systems are mostly

There is a big problem with The System having so many synchronous interactions to the outside ( web, apps, external systems) — during peak usage it can be overloaded by requests, grinding The System to a halt. Unfortunately the System is not horizontally scalable, due to how some of its business logic uses locally cached data. This problem grows for every year and every new feature added to it.

The System has a huge technical debt, the team has for many years been focusing on delivering new functionality and did not have the time to bother with updates of the fundamental technologies. You still need to deliver new functionality, but now you also have to address the technical debt, since the old components are hampering productivity and has become a security issue. Due to the requirement to constantly deliver new and changed functionality in The System you cannot just halt the development of functionality to focus on the technical debt — now what do you do?

The System as a beautiful butterfly, wishful thinking from designers in a very far past

It is time to entangle this mess of a system, and there are so many issues to address, but we need to start somewhere. The most pressing issue is system stability, so this is where we will start in the next article in the series, stay tuned!

Thank you for reading, please follow me to continue reading the article series.

--

--

CrafterOfSystems

I have been working in the software industry since 1995, in various roles, but mostly as a systems architect and full stack developer.