How to not lose your sleep while migrating a complex application
At the end of January we could finally celebrate a successful delivery of a complex system migration. Despite the hard deadline and the importance of the project, the final cut-over day was a piece of cake. Due to great planning and exceptional cooperation with our clients, we were able to de-risk the process and execute the final steps with confidence. In this article we would like to share some lessons that we learned from the project.
The background
For the last eight years one of our teams has been involved in the development of a software platform that increases the operational awareness of oil & gas production. Our client has deployed the system to several oil companies. One of their core customers, an independent Norwegian rig operator, was acquired by a bigger entity. The merger entailed a necessity to integrate the IT systems of both companies, including the software platform provided by our client.
The challenges
Fortunately, at the start of the project the applications were already running on Azure Kubernetes cluster – our client has recently completed the migration from bare VMs and we have also been involved in that process. The system was supposed to be moved to a new Kubernetes cluster within the tenancy of the acquiring company.
Our customer’s applications integrate a plethora of data sources, providing a unified analytics platform on top of them. This brought additional challenges, as moving a self-contained application is significantly easier than doing so with a platform that has, by its nature, multiple dependencies with 3rd party systems. Especially when these systems are also being migrated at the same time!
So, the following challenges had to be addressed:
- Spin up a new environment, simultaneously supporting the old one for seamless transition.
- Integrate with the existing data sources, making sure that they are reachable from the cloud. Be careful, as the vendors are moving their applications too!
- Migrate the data owned by the platform itself. It is not just a simple drag & drop, as the data needs to be adjusted to the new environment.
- Implement connectors and integrate new data sources that replace the existing ones.
The systems are used both onshore and offshore
How to deal with such a complex project?
Every project is different, but after completing a second project of such type, we want to distill a few tips that contributed to the success to share them with you.
Planning
Yes, we all know that good project planning is crucial. But how to plan it so that nothing important is missed?
Stocktaking
Carefully check what you currently have. It sounds obvious, but it’s not, especially for complex integration projects with multiple users, who can create their own content. The documentation may be helpful, but it’s good to double check and list all the features by browsing through the system. Even though we were careful, we also found a few surprises late in the project.
Grooming
When you migrate an integration platform into a new environment, some of the features may not be relevant anymore. The new organisation has their own processes and it’s wrong to assume that everything has to be moved 1:1. A perfect dashboard that nobody uses is not worth the effort.
Identifying data sources
When you compile a list of features that need to be migrated, identify the data sources currently supporting them and their counterparts within the new organisation. Data sources after an IT merger typically fall into three categories: to be moved, to be integrated and to be replaced by a similar solution.
Verifying business processes
Pay attention to any differences between the business processes supporting the migrated features. They may have an impact on user or data workflows.
Getting in touch
Nothing works better than direct contact. Even though the meetings may be cumbersome, they work well during the first phase of the project. It’s important to engage not only with the users of your software, but also try to establish contact with the key technical personnel of the 3rd party vendors. Such communication channels are invaluable for coordinating the migration process.
Defining early milestones
Approach the challenge iteratively! Make sure to plan some preliminary integration tests far before the actual deadline. This may seem unnecessary at first, especially when the final cut-over date is still far away, but early milestones help expose hidden dependencies and assumptions while there is still time to react.
Involving the end-user early
Do not wait until everything is “done” to show the results to the users. Even if the system is only partially migrated, early feedback from real users is invaluable. They can quickly tell you which features are business-critical, which ones are merely nice to have, and which workflows no longer make sense in the new organizational setup.
Software architecture
As software developers we know that a badly designed application may make the process of doing changes a nightmare. We learned the good and bad ways what is especially important when designing an application that should be easy to adjust and migrate:
Define generic interfaces
Generic interfaces act as shock absorbers during migration. When external systems, data providers, or deployment environments change, well-designed interfaces allow you to swap implementations without rewriting large parts of the application. This proved especially important when integrating with systems that were themselves in flux, as it minimized the ripple effects of late changes.
Define contracts between modules
Clear contracts make responsibilities explicit and reduce ambiguity. When each module clearly states what it expects and what it provides, teams can work in parallel with confidence. During migration projects, contracts also serve as a safety net, ensuring that changes in one area do not silently break functionality elsewhere.
Don’t spread business logic
Business logic scattered across services, UI components, and integration layers is hard to reason about and even harder to migrate. Centralizing business rules makes them easier to test, adapt, and validate in a new environment. It also helps when business processes evolve as part of a merger, which is almost always the case.
Encapsulate
Encapsulation limits the blast radius of change. By hiding internal details behind well-defined boundaries, you reduce coupling and make the system more resilient to refactoring. This becomes crucial when infrastructure, security models, or data sources differ between the old and new environments.
Think product-wise (configurability) to avoid re-doing from scratch
Features that are configurable rather than hard-coded are far easier to migrate. A product-oriented mindset encourages building flexible solutions that can be adapted through configuration instead of code changes. This not only speeds up migration but also helps align the system with the new organization’s processes.
Take the opportunity to improve
A migration project inevitably exposes technical debt. While it is rarely feasible to fix everything, selective improvements can pay off quickly. Removing obsolete components, simplifying overly complex flows, or improving observability can make the migrated system more stable and easier to operate in the long run.
Keep the docs up to date
Documentation tends to lag behind reality, especially in long-running projects. During migration, outdated documentation can be more harmful than none at all. Keeping architecture diagrams, integration descriptions, and operational notes current saves time, reduces misunderstandings, and helps onboard new stakeholders involved in the process.
Embrace collaboration
Architecture is not created in isolation. Close collaboration between developers, operations, security teams, and external vendors leads to better decisions and fewer surprises. Open communication channels make it easier to resolve issues quickly and align technical solutions with real-world constraints.
Summary
Migrating a complex application in the context of an organizational merger is never just a technical exercise. It is a combination of careful planning, clear communication, architectural discipline, and continuous validation. The technical challenges are often intertwined with changing business processes, evolving data sources, and shifting responsibilities across teams and vendors.
What helped us succeed was breaking the problem down into manageable steps, validating assumptions early, and involving the right people at the right time. Early milestones reduced uncertainty, while close collaboration with end-users ensured that we were building what actually mattered. An equally important contributing factor was the excellent project management on the client’s side, which helped coordinate the project in a constantly changing landscape, where systems, dependencies, and responsibilities were evolving throughout the migration.
On the technical side, solid architectural principles allowed us to adapt to change without losing control of the system. In the end, a smooth cut-over is rarely the result of last-minute heroics. It is the outcome of many small, deliberate decisions made throughout the project. With the right mindset, strong cooperation, and good project management, even a complex migration can become a predictable and, dare we say, almost boring exercise — and that is exactly how such projects should feel.






