Strangler figs start as epiphytes, eventually killing their host trees through constriction.

Strangler Fig Pattern and Other Methods for Legacy Travel System Migration: Hands-on Experience

This article will clarify the difference between the three methods of legacy system migration—strangler fig pattern, incremental updates, and rewriting from scratch. We’ll cover best practices, use cases, and the pros and cons of each approach, along with insights from our personal experience migrating legacy travel systems.

Before we dive in, here’s a quick explanation of the three approaches in simpler terms.

  • The strangler fig pattern is like building a new house next to your old one and gradually moving all of your belongings into the new house.
  • The incremental update involves renovating one room at a time but still staying in the same house.
  • Rewriting from scratch means building a new house, moving in only after it’s finished, and abandoning the old house entirely.
Comparing the three methods of legacy system migration

Comparing the three methods of legacy system migration

Why do we need legacy system migration?

A legacy system is an outdated computing system—whether hardware, software, or both. It lacks compatibility with newer technologies, modern UI, and scalability. However, many businesses still rely on them for critical daily operations because

  • they perform their intended functions effectively;
  • upgrading to a new system requires significant upfront investment; and
  • employees may be hesitant to adopt new processes, fearing disruption in their daily operations or a steep learning curve.

What forces companies to migrate from legacy systems?  Here are key reasons that make our clients  — online travel agencies, property management companies, and other travel businesses  — consider moving to newer technologies.

Why we need legacy system migration

Why we need legacy system migration

Cost efficiency. While a legacy system may seem like a way to avoid upfront costs, the ongoing support and maintenance expenses can far outweigh the initial savings. For example, finding specialists to manage outdated technologies can be difficult and expensive. So, in the long run, migrating to modern systems will reduce operational costs.

Security. Legacy systems often lack modern security features and no longer receive critical updates and bug fixes, making them vulnerable to cyberattacks and data breaches. Migrating to newer systems allows businesses to safeguard sensitive data and comply with proper security standards.

Scalability. As businesses grow, they need systems that can scale with their operations. Legacy systems often lack the ability to expand or accommodate new features and workloads.

Access to support. Most legacy systems eventually lose vendor support, making it harder to find patches, updates, or expertise to resolve issues.

Compatibility. Legacy systems lack compatibility with modern systems, which makes intergating new features difficult or impossible. This stifles innovation, and organizations face the choice of either modernizing or risking falling behind competitors.

We would also like to clarify the difference between legacy system migration and legacy system modernization. The former involves moving data, applications, or entire systems from outdated technology to a new environment, while modernization retains some core functionality and is about updating or enhancing certain parts of the existing legacy system.

A general overview of legacy system migration methods

A general overview of legacy system migration methods

Now let’s dive into the three approaches of legacy system migration—strangler fig pattern, incremental updates, and rewriting from scratch.

Strangler fig pattern: Simultaneous operation of legacy and new systems for a gradual transition

The strangler fig pattern is a method used to gradually replace a legacy system with a new one without having to shut down the former all at once. The name comes from the strangler fig tree, which slowly grows around a host tree until it eventually takes its place.

This approach minimizes disruptions and ensures continuity for users. “You build the new system alongside the old one, and specific features or functions are progressively moved over to the new platform,”  explains Ivan Mosiev, a solution architect at AltexSoft who led several migration projects for travel businesses.  

The process of the strangler fig pattern

The process of the strangler fig pattern

The process of the strangler fig pattern

The strangler fig pattern has a facade that acts as a proxy, determining whether requests go to the old or new system. As new modules are built into the new system, more requests are routed to it. Over time, the old system becomes less and less important, and it can eventually be shut down.

Strangler fig pattern pros and cons

Let's discuss the key advantages of the strangler fig pattern.

Reduced risk. The pattern minimizes migration risks by allowing gradual changes, ensuring the old system remains functional while new features are introduced.

Zero downtime. The old system remains operational, ensuring that there is no downtime during the migration process and that users remain unaware of the transition as they continue interacting with the same interface.

Simpler testing. As parts of the legacy system are replaced by the new system, each section can be tested individually, allowing us to focus closely on separate features or modules.

Quick feedback loop. Using the strangler fig pattern, you can rewrite parts of the system and deploy them to users immediately. This allows for early feedback on the changes and the introduction of new features that didn’t exist in the old system.

The disadvantages of this legacy system migration method follow.

Resource сonsumption. Since the legacy system continues to operate until fully replaced, resources are needed for both systems throughout the migration process. Overall resource consumption will be higher than that of other methods.

The main drawback of the strangler fig pattern is that we have to run two systems simultaneously. We cannot separate them and get them to work smoothly without anyone noticing.

Ivan Mosiev, Solution Architect at AltexSoft

Synchronization challenges. The strangler fig pattern requires building temporary services and connections to allow the old and new systems to work together during the transition. This can create challenges in terms of data synchronization.

Suppose a travel agency starts building a new booking system alongside the old one. Both must keep customer profiles and booking histories in sync, and the agency needs to ensure that the reservations made in the new system are correctly reflected in the old one.

Transition complexities. Even though the strangler fig pattern avoids a one-time massive switch, there are many smaller transitions throughout the migration process. “There’s an ongoing need to analyze how changes impact the legacy system, which adds complexity as you're dealing with both systems in parallel until the migration is finished,” — Ivan Mosiev says.

Strangler fig pattern use cases

This method is most effective in two scenarios.

Migration without service disruptions. The strangler fig pattern is well-suited for situations where it's critical to keep the business running throughout the migration process. Both systems operate side by side to ensure continuous availability and avoid service disruptions. If the new system encounters issues, the legacy system remains in place as a fallback to ensure smooth operations.

Replacing very old systems. This method is also applied when a legacy system is extremely outdated—so old that either the engineers who built it are no longer available or updating it isn’t worth the time and resources.

At AltexSoft, we implemented the strangler fig pattern when migrating a legacy property management system (PMS) that was over 20 years old.

Our team updated the database structure by adding new tables and introducing new functionality while ensuring compatibility with the legacy system. As new parts were deployed, we gradually transitioned to the modern architecture.

Incremental update: Enhancing one system piece by piece

The incremental update focuses on modernizing sections of the existing codebase. Each rewritten part is incrementally integrated back into the main system.

The process of incremental update

The process of incremental update

Once a piece is rewritten, it’s deployed instead of the old feature, so only one system operates in production during the migration period.

Incremental update pros and cons

This approach shares some pros with the strangler fig pattern—quick value delivery, simpler testing, and zero downtime. But it also has unique advantages.

Resource efficiency. Since you're upgrading the current system piece by piece, you’re only using the resources required for one system and its existing features, making this approach the most efficient in terms of memory and computing power.

Smooth transition. The incremental update strategy involves making changes to the legacy codebase in small, manageable parts. You can rewrite parts of the system and deploy them while keeping the existing system operational. This allows for a smooth transition and minimizes the chance of large-scale failures.

Although the incremental update is the most cost-efficient of the three methods, we can pinpoint one scenario in which this approach falls short.

Impractical with not recent systems. Some systems are not too outdated but are still not feasible for incremental upgrades. For example, software using the 4th version of a programming language is not compatible with the current 8th version. Here, adding new features is impossible because the older version simply does not support the required functionality or modern libraries.

In such cases, the better approach would be to completely replace the old system by building one from scratch or use the strangler fig pattern.

Incremental update use cases

An incremental approach is ideal for systems that are just a version or a couple of versions behind the most recent release of a programming language, framework, or environment.

Ongoing projects. Incremental upgrades are often used for systems that are already in production and are undergoing continuous development. New features are regularly added without needing to overhaul the entire system.

Framework and language version upgrades. This method is effective for updating systems to new frameworks or programming language versions. Incremental updates are considered the cheapest and least risky option, provided they are done regularly—typically every few years.

Every programming language has a lifecycle, with each version eventually becoming obsolete. We aim to work with long-term supported versions, which provide stability and security for a few years,”  Ivan Mosiev shares. “When a new long-term support version is released, we know that we have about two years to continue using the current version before an upgrade is necessary.

System scaling. If a system was originally built for a certain number of clients or level of traffic and its needs have significantly increased, an incremental update is the best choice. For example, you might upgrade components responsible for handling user requests, optimize database performance, or gradually enhance server capacity.

Organizational changes. Changes within an organization, such as new workflows, business processes, or culture shifts, can be managed incrementally to allow employees to adapt progressively. Organizations can provide targeted training and support for each phase to help employees adjust gradually.

Switching APIs. Businesses can apply this approach to update their APIs. For example, two major GDSs, Sabre and Amadeus, are incrementally moving from SOAP to REST API architecture. Yet, this possibility must be embedded into the software architecture. As Ivan Mosiev says, “Incremental changes are suitable only for isolated components.” Otherwise, if the system is highly interconnected, it may require a full rewrite due to the complex dependencies.

At AltexSoft, we usually use the incremental approach. For example, we updated the backend of a booking widget built with a relatively recent version of PHP. The underlying technology was modern enough to work alongside rewritten parts.

Rewriting from scratch: Building a new system to replace outdated technology

Rewriting from scratch involves a one-time gib transition from the old system to the newly built one. It is ideal for old monolithic software where making changes to individual components is impractical because any modification affects the entire system.

The process of rewriting a system from scratch

The process of rewriting a system from scratch

This approach provides an opportunity to completely redesign the system with a modern, scalable architecture that is easier to maintain and adapt to future needs.

Rewriting from scratch pros and cons

Here are the advantages of this approach.

Resource efficiency. During a rewrite from scratch, the old legacy system runs until the new system is ready to replace it. This means you’re only consuming resources to support the existing system until the entire rewrite is complete. Unlike the strangler fig approach, where both systems are active, the full rewrite doesn’t require running two systems at once.

At the same time, there are situations when it’s critical to run both platforms in parallel. For example, when the AltexSoft team rewrote a booking website for a vacation property management company, the fresh version captured all new bookings while the old system was temporarily retained to manage previous reservations.

The old and new platforms relied on different booking number formats, which helped distinguish them. If users entered booking numbers in the old format, they were automatically directed to the legacy system. This way, we reduced the load on the old system and ensured a smooth transition to the new one. Cost efficiency was somewhat sacrificed for the sake of lower risks.

More control. Rewriting from scratch gives you full control over the codebase, enabling a customized, up-to-date solution that meets current requirements and best practices. You have the freedom to implement features and functionalities exactly as desired without being constrained by the limitations or outdated structures of the existing system.

No technical debt. When you rewrite a system from scratch, you have the opportunity to build it using the latest programming language versions, design patterns, and best practices. This means you can avoid the outdated methods and technologies that contributed to technical debt in the old system.

Technical debt is like taking shortcuts that might speed up initial development but lead to problems and inefficiencies later on. Over time, it can create issues such as bugs, performance problems, and difficulties in maintaining or updating the system.

Ivan Mosiev, Solution Architect at AltexSoft

The full rewrite also has certain drawbacks.

Risk of disruptions. During the transition, the existing system may be taken offline to switch over to the new platform. Even brief periods of downtime can impact business operations and customer satisfaction. Another possible issue here is data migration. For example, some customer orders and transaction history on an eCommerce platform might get lost or incorrectly transferred.

Complex testing. A full rewrite requires testing the entire system to ensure it works as intended, whereas two other approaches involve testing smaller sections one at a time.

Longer time to market. Rewriting an entire system takes more time than rewriting separate parts. As a result, organizations may deliver new features and capabilities later than competitors. They also can’t quickly respond to changing market needs.  

Cost considerations. This approach is more expensive due to the extensive development, longer project timelines, and comprehensive testing required to build a new system from the ground up.

Rewriting from scratch use cases

Due to its complexity and significant investments, rewriting from scratch is not always the most optimal approach. However, it is practical in certain scenarios.

No vendor support. If the system relies on software or hardware that is no longer supported by the vendor, it becomes difficult to update or maintain. Without access to security patches or technical assistance, continuing with the old system can pose significant operational risks.

For example, at AltexSoft, we completely rebuilt vacation rental software as it was heavily dependent on an outdated PMS that was no longer supported. Rewriting the system from scratch allows us to create a new, platform-agnostic solution capable of handling property data efficiently.

Little to no code visibility. In many cases, the developers who built the original system are no longer available, and the current team may have a limited understanding of the code logic. This makes it hard to apply small changes without introducing risks or breaking the system.

In our practice, we worked with an OTA that used a white label solution, meaning that their booking platform was not developed in-house. Since we didn’t have access to the original code, an incremental update was not an option.

Theoretically, we could have gone with the strangler fig pattern: The old external system could be masked under a proxy, gradually redirecting part of the traffic to the new in-house system. However, in this case, a full rewrite made more sense as it was easier to start fresh rather than work around the limitations of an external system.

Legacy system migration best practices

To ensure a smooth and successful legacy system migration, we recommend the following best practices.

Code analysis. Begin by exploring the extent of legacy code issues and how they affect the system. This helps identify the best migration approach. For example, you can ask yourself if the system is recent enough for the incremental update or whether it is easier to rewrite from scratch to avoid dealing with the constraints of outdated technology.

Migration plan. Establish a timeline for each migration phase and identify the needs and goals of the new system, such as improved user interface, scalability, and integration capabilities. Align the migration process with long-term business objectives, ensuring the new system supports future growth.

Migration scope. Identify the data and processes that will move to the new system, ensuring compatibility and security. For example, when migrating a hotel reservation system, the scope may include customer data, booking histories, room availability, reservation management, and reporting.

Technology selection. When choosing technology for your business needs, consider both current requirements and future scalability. For example, a legacy flight booking system built on a monolithic architecture might struggle to handle modern demands, such as real-time access to fares and personalizing customer offers.

Engage stakeholders. Communicate the importance of modernizing the legacy system. Ensure all departments and stakeholders are informed, as migrations impact the entire organization.

Comments