One of the main challenges transportation and logistics companies face now is relying on legacy software systems that are outdated and difficult to maintain or update. These systems often lack scalability, real-time process visibility, and automation, hindering efficiency and competitiveness.
Recently, I was part of a long and intricate project for one of the world’s biggest logistics companies. It required fixing and modernizing the core legacy system to increase efficiency. In the following article, I will share my thoughts and lessons learnt during the process.
Legacy systems in transportation – challenges
Technology remains imperative for organizations in the transportation and logistics domain. A recent Gartner survey found that 61% of respondents believe technology in the supply chain gives them a competitive edge. According to a Deloitte survey, on the other hand, average IT departments spend over 55% of their tech budget on maintaining business operations and only 19% on developing innovative solutions. Relying on old, cumbersome systems, however, leads to:
- Inefficiencies: Legacy systems may lack the capabilities to optimize routes, manage cargo, or handle real-time tracking. This can result in increased fuel costs, longer delivery times, and inefficient resource allocation.
- Inaccuracy: Legacy systems might not provide real-time data or accurate reporting. This can lead to delays in decision-making, inaccurate invoicing, and customer dissatisfaction.
- Maintenance costs: Maintaining legacy systems is more expensive than modernizing them. According to the United States Government Accountability Office, ten of the government’s legacy systems cost approximately $337 million annually to operate and maintain.
- Lack of scalability: As transportation companies grow, legacy systems may struggle to handle increased data volume and demand, leading to performance issues and missed business opportunities.
Although modernizing old systems sounds like an inevitable next step for transportation companies, many are facing a handful of obstacles:
- Complexity: Legacy systems have grown intricate over time to handle specific tasks. Untangling this complexity without disrupting operations poses challenges.
- Lack of documentation: Documentation for legacy systems may become outdated or nonexistent over the years. This can hinder understanding their complexities and planning for effective modernization.
- Integration challenges: Modernizing systems often involves integrating them with other software and hardware components. Ensuring smooth integration can be tough.
- Lack of in-house expertise: Finding professionals with expertise in both legacy and modern technologies is usually quite difficult, given the evolving nature of technology.
This was the case with our client. Their old, cumbersome system was inefficient but due to its complexity, lack of documentation and in-house expertise, they were unable to fix it.
How we overcame legacy system challenges with a tailored approach
Our client is one of the largest transportation and logistics companies in the world. Their core product featured a legacy system, initially designed for the German market. Upon the advancement of Brexit, the company needed to adjust it to the new local-specific compliance of the UK market regulations.
Throughout the years, external vendors piled up legacy code to the system, which was combined with big people turnover. Therefore:
- Declarations were not processed accurately
- Trucks were slowed down at customs
- Clients were complaining
The company reached out to us as their software for processing customs declarations was 10 years old, with loads of performance issues in the flow that needed to be resolved.
One of the issues our team spotted from the start was that due to the high people turnover, developers and product owners were unable to gain a deep understanding of the domain or how the system works and missed business context.
The only way to solve any of the issues, however, was not to focus on the actual technical problems. Instead, we had to find a way to understand the business logic behind the software.
We could gather that information only from the code itself. So we dived deep.
Start with reverse engineering
Reverse engineer the business from the implementation. This is more challenging than it sounds. Technical implementations are done based on the business understanding that the developer had at the time of development. Because of this subjectivity, wrong assumptions were likely made. Oftentimes, when issues are discovered after the initial implementation, developers generally try to find “quick and easy” solutions rather than redesign everything correctly from the beginning. Imagine patching the system with such “quick and easy” solutions for years. The result is no less than a cluttered system containing incorrect or unused code.
Next, don’t touch it
The next step, right after we understand the code and the business behaviour, is not to touch it. Before we make any changes, we need to ensure the system works as expected. If the codebase already has tests – that would help, but often tests are either incomplete or completely missing.
We implemented a complete test suit that tested the whole business logic. We covered all possible branches in the code execution to ensure that once the refactoring starts, the system will maintain its main functionality correctly. That process was lengthy but rewarding as once completed, we had a reproducible test.
Spot other malfunctioning elements
At this point, we should start seeing other obvious points in the system that can be improved. Such could be loading the same business objective twice, doing unnecessary transformations, having queries that are too complex, etc. In our case, we found a query that did two Join Sql statements. You might say that this is pretty standard and you would be completely correct; however, the tables that were being joined had billions and millions of records respectively. The issue was that the query joined the ‘billions’ records first and after that – the ‘millions’. Usually, the rule with Joins is to always join smaller tables first. We switched the join, and just that one query improved the execution from 10 minutes to around 40 seconds.
Document, document, document
After we applied our improvements, we documented everything so that the next person in charge of that system, can at least build upon our knowledge. We documented the business flows and test suites. This was a core business logic domain that was extracted from our work and could be useful for anyone, not only developers. Finally, we documented the technical aspects, which allowed us to get up to speed quickly in case we needed to make changes again.
We improved the transaction time from over 10 minutes to 8 seconds.
The execution time sped up so much that the queue which was piling up for months, was cleared in less than 24 hours. This uncovered other issues that the system had, but after a couple more iterations of that same approach, the system was stable enough to consume tens of thousands of messages per day! Prior to these improvements, it could barely process hundreds.
The stakeholders were extremely pleased with the results. They were seeing declarations flying in. The relatively small changes that we made had such a big impact on the business. This is a testament to the pay-off that quality work can have on people and their working lives.
Resolving those critical technical problems and improving the core system’s performance by 150 times gained our client’s trust. Only now could we propose to modernize the legacy system by changing its whole architecture. It would cost more at first, but in the long run – it would be scalable and much more efficient. They agreed.
Fast-forward a couple of years and the old legacy monster is now being devoured by a new service, piece by piece. We are migrating the old functionality and scaling up our operations.
We also have perfectly synched teams on both sides that continue to modernize and implement innovative features to optimize our client’s processes and gain them a competitive edge.
When we first engaged in the project, we questioned why developers, product owners and managers prior to us were unable to solve the case. Since they were focused solely on the technical aspect of the case, they were straying from the core business problem.
Now, looking back at the beginning of that journey, several key takeaways come to mind:
- Don’t focus on the technical problems in the project. Rather, seek information on a business level. Find the biggest issue and solve it.
- Initiate conversations with the stakeholders to better understand their challenges. Then, look for ways to address them.
- Look for technical solutions that can solve the business problem.
- Be pragmatic.
Learn more about our tailored approach.