Software Engineering
Legacy Application Migration Services
The big-bang rewrite is the classic, expensive way legacy modernisation fails. We do it the other way, make the old system safe, then replace it a piece at a time while it keeps running.
What Legacy Application Migration means in practice
Who it’s for: Organisations running old, business-critical software that has become risky to change (unsupported technology, no tests, ageing infrastructure, the original team gone), who need it modernised without betting the operation on a single risky launch.
A legacy system is not simply old software; it is software the business still depends on that has become dangerous to change. The framework is years past its supported release, the language version no longer receives security fixes, the infrastructure it runs on is ageing hardware or a cloud configuration nobody remembers building. There are few tests, or none. The documentation was never written, or is out of date in ways nobody can predict. And the people who built it: the ones who knew why a particular piece of code is shaped the way it is, have moved on. What is left is a system that works, mostly, but that everybody is afraid to touch, because the cost of an unexpected break is high and the ability to see it coming is low.
Legacy application migration and modernisation is the work of getting such a system onto a supported, maintainable, current footing without stopping the business that runs on it. That is harder than building something new, because you are operating on a live patient. The single most important decision in the whole endeavour is how you go about it, and the industry is littered with organisations that chose the tempting answer, the big-bang rewrite, and spent years and a fortune discovering it was the wrong one. Our strong preference, in nearly every case, is the opposite approach: incremental migration using the strangler-fig pattern, where the new system grows up around the old one and takes over its work a piece at a time until the old system can be quietly retired.
We are also honest about the option nobody selling a rewrite will mention: sometimes the right answer is not to migrate at all. A stable, working legacy system that the business has no need to change is not automatically a problem to be solved. If it is secure, if it is not blocking anything, and if it is not costing much to keep running, leaving it alone may be the most sensible decision on the table. Our job is to give you a straight assessment of which situation you are actually in, not to manufacture a large modernisation programme because that is what we happen to sell.
What you get
- A clear-eyed assessment of what you actually have. The code, the data, the infrastructure, the dependencies, the undocumented behaviour and the real risks, before anyone recommends a direction
- A strategy chosen on your constraints, honestly argued: whether to migrate, and if so whether to re-host, re-platform, refactor, re-architect or replace, and crucially, in what order
- Safety nets built first: automated tests around the risky and important parts, observability so we can see what the system really does, and documentation of how it actually works, so change becomes safe rather than terrifying
- Incremental migration using the strangler-fig pattern: the new system built around the old, traffic routed across piece by piece, the old system retired gradually and only once its replacement is proven
- A data migration plan that treats your data as the crown jewels, validated, reconciled, and moved without loss, with old and new able to run in parallel during the transition
- Security brought current as part of the work, because a legacy system is usually a stack of unpatched, known vulnerabilities, and migration is frequently a security necessity as much as a technical one
- A path to ongoing maintenance and support once the migration is done, so the modernised system does not simply become tomorrow’s legacy for want of upkeep
Work like this
Real engagements, written with the client’s own facts and published as they are approved.
What Legacy Application Migration does for you
The risk is contained at every step
The reason incremental migration is worth its slower feel is that it never puts the whole business on the line at once. Because the strangler-fig approach replaces one piece at a time behind a stable facade, there is always a working system in production, and any single step is small enough to verify, and reversible if it misbehaves. Compare that to the big-bang rewrite, where the new system is invisible and unproven for months or years, the switch-over is a single high-stakes event, and the failure mode is catastrophic and total. We choose the approach where a mistake costs you a step, not the operation.
A security exposure closed rather than left to widen
A legacy system is very often a stack of known, published, unpatched vulnerabilities (in the framework, the runtime, the libraries, the operating system), that are public knowledge and therefore public knowledge to attackers too. That is why a migration is frequently a security necessity as much as a technical one. Bringing the system onto a supported, patchable footing closes a door that has been quietly open, sometimes for years. For many organisations this is the single most valuable outcome of the whole exercise, even before anyone counts the improvements in maintainability or speed.
A system your team can actually work on
The compounding cost of legacy is not the technology itself but what it does to your ability to change. When there are no tests, no documentation and no one who understands the system, every feature takes longer, every fix carries risk, and hiring is hard because few people want to work on dead technology. A modernised system (current stack, tests, observability, documented), turns that around: changes become routine, bugs become findable, and you can recruit engineers who are glad to work on it. The value shows up in every piece of work the business does thereafter.
Why teams choose us for Legacy Application Migration
- You want someone who will tell you honestly whether to migrate at all, including that a stable, working system with no change needs may be fine left alone, rather than a supplier who sees every old system as a large rewrite waiting to be sold.
- You have a scary, undocumented system that the original team walked away from, and you need people who take that over deliberately (learning it, making it safe with tests and observability, then modernising it), rather than either refusing to touch it or rewriting it blind.
- You have been burned by, or are rightly afraid of, the big-bang rewrite, and you want a partner whose default is incremental migration that keeps the business running throughout.
- You understand that the migration is partly a security exercise (an ageing, unpatched stack is an open door), and you want that treated as a first-order goal, not an afterthought.
What Legacy Application Migration includes
The concrete pieces of work this covers, scoped to what your problem actually needs.
Legacy assessment and strategy
Before recommending anything we survey what you actually have: the codebase and its real behaviour, the data and its quality, the infrastructure and its support status, the dependencies and their known vulnerabilities, and (most importantly), where the undocumented risk lives. From that we give you a strategy argued on your constraints: whether to migrate at all, and if so whether the right move for each part is to re-host, re-platform, refactor in place, re-architect or replace outright. Different parts of one system often warrant different answers, and the order of operations matters as much as the choices themselves.
Stabilising an unfamiliar, undocumented system
Taking over a system nobody understands is a distinct discipline, and it is one of our real strengths. We get it into version control and a reproducible build if it is not already, stand it up somewhere we can safely poke at it, read the code alongside its actual behaviour, and write down how it really works as we learn. We add observability so the system stops being a black box, and put automated tests around the parts where a mistake would cost the most, because you do not need full coverage to make change safe, you need coverage around what you are about to touch and what must never break.
Strangler-fig incremental migration
This is the core of how we modernise. We place a facade in front of the legacy system so that callers do not know or care which implementation answers, then replace functionality one bounded piece at a time: building the new, routing traffic to it, verifying it against the old behaviour, and retiring the corresponding old code only once its replacement is proven in production. The new system grows around the old and slowly strangles it, until what remains of the legacy system is small enough to switch off. At no point is the business without a working system.
Data migration and reconciliation
The data is usually the part that cannot be recreated and cannot be lost, so we treat it with corresponding care. We map the old schema to the new, deal honestly with the years of accumulated inconsistencies that every long-lived database contains, migrate in a way that can be validated and reconciled record for record, and (where the migration runs over time), keep old and new stores in sync so both systems can operate in parallel during the transition. The switch-over of data is planned, rehearsed and reversible, never a hopeful one-way leap.
Running old and new in parallel
A safe incremental migration spends much of its life in a hybrid state, with parts served by the old system and parts by the new, and that state has to be engineered deliberately rather than tolerated. We manage the routing, keep data consistent across the boundary, and where it is valuable run the old and new implementations side by side on the same traffic to compare their outputs before cutting over, so a discrepancy is caught by us in a comparison, not by a customer in production. The parallel-running period is where the risk is genuinely retired.
Security and dependency modernisation
A large part of migrating a legacy system is bringing its security posture into the present. We inventory the stack against published advisories, move off unsupported framework, runtime and operating-system versions that no longer receive fixes, replace or update vulnerable dependencies, and close the configuration weaknesses that ageing systems accumulate. Because this is so often the real urgency behind a migration, we sequence the work so that the most exposed, most exploitable parts are among the first to be modernised rather than the last.
Where it fits
The unsupported framework running the business
A core application is built on a framework and language version that reached end of life years ago. It still works, but it no longer receives security patches, the hosting is increasingly hard to keep alive, and hiring anyone who will maintain it is nearly impossible. We stabilise it, then strangle it, standing up a modern replacement piece by piece behind a facade and routing traffic across as each part is proven, so the business moves onto a supported footing without a single high-risk cut-over.
The system whose builders are all gone
A business depends daily on software whose original developer, agency or team has long since departed. There are no tests, no meaningful documentation, and every change is met with held breath. We take it over the careful way, learn it as it really is, add observability and tests around the risky parts, document how it actually works, and only then begin to modernise, turning a system nobody dared touch into one that is understood and safe to evolve.
The migration that is really a security fix
An insurer, customer or regulator has started asking hard questions about a system running on an ancient, unpatched stack, and the honest answer is that it is full of known vulnerabilities nobody can close without upgrading the platform underneath. Here modernisation is a security necessity. We prioritise the most exposed components first, moving them onto supported, patchable technology, so the open doors are shut in order of how easily an attacker could reach them.
The system that can no longer accept new features
The business needs a new integration, a new workflow, a new capability, and the legacy architecture makes each one enormously expensive or outright impossible. Rather than pour more money into fighting the old design, we migrate the relevant parts incrementally onto an architecture that can actually accommodate change, so the features the business has been unable to ship become routine work again on a system built to accept them.
How we approach Legacy Application Migration
We earn the right to change the system before we change it. That means the first work is rarely migration at all: it is understanding. We learn the system as it actually behaves, get it into version control and a reproducible build if it is not already, add observability so we can see what it does in production rather than guess, and put automated tests around the parts that are both risky and important. Only once there is a safety net do we start moving anything, because migrating a system you cannot see and cannot test is how a stable-but-fragile system becomes an unstable one.
From there we migrate incrementally and refuse the big-bang. We identify a seam (a bounded piece of functionality with a clear edge), build its replacement, route traffic to the new implementation behind a facade, verify it against the old behaviour, and only then move on to the next piece. The business keeps running throughout because at every moment there is a working system; we are never in a state where everything is half-migrated and nothing is deliverable. Each step delivers value and de-risks the next, and if a step goes wrong we can reverse it without unravelling the whole programme.
How a migration engagement runs
We begin with assessment, not a plan to rebuild. We establish what the system is, what it does, what it runs on, what it depends on, where the data lives and what state it is in, and (the part that takes real work), how it actually behaves, including the undocumented rules and the fragile corners. Out of that comes an honest recommendation: whether to migrate at all, what strategy fits each part, in what order, and what the risks are. If the right answer is to leave a stable system largely alone, we will say so; if it is to modernise, the assessment is what makes the rest safe.
From there the work runs as a sequence of small, deliverable steps rather than a single long march to a distant launch. We build the safety nets first, then place a facade in front of the legacy system, then replace functionality one piece at a time: building, routing, verifying against the old behaviour, and retiring old code only once its replacement is proven. Data is migrated and reconciled with old and new kept in sync where the transition spans time. At every point there is a working system in production, progress is visible in the product rather than in a status report, and any single step can be reversed without endangering the whole. When the last piece is strangled, the legacy system is switched off, and the modernised system moves onto ongoing maintenance so it does not become tomorrow’s legacy.
Incremental migration, data, and running old and new in parallel
The architectural heart of a safe migration is the strangler-fig pattern, and the mechanism that makes it work is a facade placed between the callers of the system and the system itself. Once traffic flows through that facade, we can decide per request or per feature whether it is answered by the old implementation or the new one, and we can move that boundary a piece at a time. The new system is built around the old, taking over bounded slices of functionality, and the old code for each slice is retired only after its replacement has proven itself on real traffic. This is what lets the business run continuously through a migration that may take many months: there is never a moment when the system is neither the old thing nor the new thing but a broken half of both.
Data is the part that demands the most discipline, because it cannot be lost and usually cannot be paused. We map the legacy schema onto the new one, confront the accumulated inconsistencies that every long-lived database carries rather than pretending they are not there, and migrate in a way that can be validated and reconciled rather than trusted blindly. Where the transition spans time (as incremental migrations almost always do), old and new stores are kept in sync so both systems can operate against consistent data in parallel. That parallel-running period is not an awkward interim to be rushed through; it is where the risk is actually retired. Running the old and new implementations side by side on the same traffic and comparing their outputs is how a subtle discrepancy is caught by us in a comparison rather than by a customer in production, so that when we finally cut a piece over, we already know it behaves.
Why a legacy migration is so often a security necessity
The uncomfortable reality of most legacy systems is that they are, from a security standpoint, a stack of open doors. The framework version is one that stopped receiving fixes years ago; the language runtime and operating system are past their supported life; the libraries the system pulls in have accumulated published vulnerabilities that were never patched because patching meant an upgrade nobody dared attempt. Every one of those is a known, catalogued weakness: known to you only vaguely, but known to attackers precisely, because vulnerability databases are public and automated scanning for unpatched systems is constant. A legacy system that has been running untouched is not safe because nothing has happened yet; it is exposed, and the exposure widens with every advisory published against the technology it is frozen on.
This is why, for a great many organisations, a migration is driven as much by security as by any feature or cost pressure, and why we treat the security dimension as a first-order goal rather than a tidy-up at the end. We inventory the stack against published advisories to understand exactly where the exposure is, and we sequence the incremental migration so that the most exploitable, most exposed components are among the earliest to be moved onto supported, patchable technology. Moving off end-of-life platforms, replacing vulnerable dependencies and closing the configuration weaknesses that ageing systems accumulate is not a side effect of modernisation; for many systems it is the main event. And because the modernised system is left on a supported footing with a maintenance and patching cadence, the doors do not simply drift open again the moment we leave.
Signs it’s time
- The technology is unsupported. The framework, language version, database or operating system no longer receives security fixes or updates, and you are running on borrowed time
- It has become a security risk. You know there are unpatched, known vulnerabilities in the stack, and the longer the system stays as it is, the wider the exposure grows
- Nobody left in the building understands the system. The original developers, agency or team are gone, there are no tests and no documentation, and every change is a gamble
- Maintenance cost is rising. The system is increasingly expensive to keep running, specialists in its ageing technology are scarce and costly, and small changes take far longer than they should
- You cannot add the features the business needs. The architecture fights every new requirement, integrations are impossible or brittle, and the system is now actively holding the business back
Our working method, and our honesty about the rewrite
The principle that organises this entire service is a blunt one: the big-bang rewrite is the classic, expensive way legacy modernisation fails. It is the tempting answer because a fresh start feels clean, no more wrestling with the old code, just build the right thing properly this time. What actually happens is that the new system takes years, because the old one quietly encodes a decade of business rules and edge cases nobody remembers to specify; it never quite catches up, because the old system keeps changing while the new one is being built; and the business ends up running two systems at once, paying for both, for far longer than anyone planned. We have seen this pattern often enough to refuse it as a default. Incremental migration feels slower: there is no dramatic launch, just a steady replacement of one piece after another, but it is far safer, because the risk is retired continuously and the business is never without a working system.
So our method is to understand before we change, to build the safety net before we rely on it, and to migrate in small reversible steps behind a facade rather than in one heroic leap. We measure and verify at every stage, comparing new behaviour against old rather than assuming the rewrite got it right. And running through all of it is the same honesty we apply to scope everywhere: sometimes the correct recommendation is not to migrate at all. A stable, secure, working system that the business has no need to change is not a problem simply because it is old, and we would rather tell you to leave it alone than sell you a modernisation programme you do not need. When migration is the right call, we do it the safe way; when it is not, we say so.
Technologies we build it with
Chosen per problem, not per fashion. This is the stack we most often reach for on this work.
How we deliver
- 01
Discover
We map the system, the constraints and the business it serves, including the parts nobody documented.
Architecture brief
- 02
Architect
Decisions get made, written down and defended before a line of production code exists.
Decision records
- 03
Build
Short cycles against working software. You see progress in the product, not in a status deck.
Shipping increments
- 04
Operate
Monitoring, incident response and iteration. The system is alive, so the engagement is too.
Runbooks & SLOs
Want a straight answer on Legacy Application Migration?
A short call with a senior engineer, before you write a brief. If Legacy Application Migration is the wrong answer for your situation, we will say so and tell you what we think is right.
What changes
Off borrowed time
A system on supported, patched, current technology, no longer one advisory or one hardware failure away from an incident nobody can fix.
Safe to change again
A modernised codebase with tests, observability and documentation, so adding features and fixing bugs stops being a gamble and becomes routine.
Migrated without a standstill
The move delivered incrementally, so the business ran throughout and never bet its operations on a single big-bang launch that might not have landed.
Industries we serve
Domain knowledge changes what gets built. A few of the sectors we know before the first meeting.
How pricing works
- A fixed-scope assessment to begin. A survey of the system, its data, its infrastructure, its dependencies and its real risks, producing an honest recommendation on whether and how to migrate. This is deliberately a small, self-contained piece of work, because the direction should be decided on evidence before anyone commits to a programme.
- A phased migration engagement for the modernisation itself, priced by phase rather than as one large fixed number, because incremental migration is delivered in steps, each phase can be scoped, costed and reviewed on its own, and you can pause, continue or adjust course between phases rather than being locked into a single long commitment.
- A stabilisation-first engagement where a system is too fragile or undocumented to migrate safely yet, priced for the work of understanding it, getting it into a reproducible build, and adding the observability and tests that make later change safe, as a deliberate precursor to migration.
- Ongoing maintenance and support once the migration is done, sized to the risk the modernised system carries, so it stays patched, monitored and current rather than beginning its slow slide into becoming the next legacy system.
Typical timeline
- 01
Assessment and strategy
A few weeks understanding what you actually have. The code and its real behaviour, the data and its quality, the infrastructure, the dependencies and their vulnerabilities, and producing an honest recommendation on whether to migrate and, if so, by what strategy and in what order.
- 02
Stabilise and make safe
Building the safety nets before anything moves: getting the system into a reproducible build, adding observability so it is no longer a black box, and putting automated tests around the parts that are both risky and important, so the first migration step can be taken with confidence.
- 03
Incremental migration
The main body of work: a facade in front of the legacy system, then functionality replaced one bounded piece at a time (built, routed, verified against the old behaviour, and retired only once proven), with data migrated and reconciled and old and new running in parallel as needed.
- 04
Cut-over and handover to maintenance
As the last pieces are strangled the legacy system is switched off, and the modernised system moves onto an ongoing maintenance and patching cadence, so the work does not unravel and the new system does not quietly become tomorrow’s legacy.
What working with us actually means
We take over the systems nobody else wants to touch
Inheriting a scary, undocumented, business-critical system whose builders are long gone is one of the most common reasons organisations come to us, and it is genuinely a strength rather than a favour we grudgingly do. We learn a system before we change it, make it safe with tests, documentation and observability, and only then modernise it, turning a liability everyone tiptoes around into something understood and safe to evolve.
We refuse the big-bang rewrite
We have seen the rewrite fail too many times to offer it as a default: years of effort, a new system that never catches the old one, and a business paying for both. Our default is incremental, strangler-fig migration that keeps the business running throughout and retires the risk continuously. It feels slower and it is far safer, and we will make the honest case for why that trade is the right one.
We will tell you not to migrate when that is the truth
A stable, secure, working system with no need to change is not automatically a problem, and we are not in the business of manufacturing modernisation programmes. If leaving a system largely alone is the right call, that is the advice you will get, because a straight answer is what earns trust, and we would rather be right than be busy.
We operate what we build, so we do not walk away
A migration that ends with a handover and no upkeep simply starts the clock on the next legacy system. Because we operate what we build, we set the modernised system up for ongoing maintenance and patching from the outset, and can carry that maintenance ourselves, so the investment in modernising is protected rather than left to decay again the moment the project closes.
How to engage us
Three ways to work with us on this, chosen to fit the problem, not our margin.
- Dedicated team A standing team that works only on your product, in your rituals and your tooling. Best when the roadmap outlives the project. Ongoing product development
- Staff augmentation Named senior engineers embedded into your existing team, reporting into your leads. Best when you know what to build and need capacity. Filling a capability gap
- Software outsourcing A defined outcome delivered end-to-end by an accountable team. Best when you want the result owned, not just the hours filled. Outcome-owned delivery
Related services
Part of Custom Software Development. Other work we do alongside this.
- Custom Software Development (overview)
- Web Development
- Mobile App Development
- Enterprise Software Development
- SaaS Development
- MVP Development
- API Development
- UI/UX & Product Design
- QA & Software Testing
- E-commerce Development
- Web Application Development
- Backend Development
- Frontend Development
- CMS Development
- LMS Development
- POS Development
- Database Development
- UX Design
- UI Design
- Web Design
- Android App Development
- iOS App Development
- Native App Development
- Hybrid App Development
- Manual Testing
- Performance Testing
- Automation Testing
Weighing the options
The decisions people are usually making at the same time as this one.
Common questions
Why not just rewrite the whole thing from scratch? It would be cleaner.
Because the big-bang rewrite is the classic, expensive way legacy modernisation fails, and we have seen it happen too often to recommend it lightly. A fresh start feels clean, but the old system quietly encodes years of business rules and edge cases that nobody remembers to write into the new specification, so the rewrite takes far longer than planned. Meanwhile the old system keeps changing to meet the needs of the business, so the new one is chasing a moving target and never quite catches up, and you end up running and paying for two systems at once for years. Incremental migration using the strangler-fig pattern avoids all of that: we replace the system a piece at a time behind a facade, so the business keeps running, the risk is retired continuously, and any step can be reversed. It feels slower because there is no dramatic launch, but it is dramatically safer, and it actually finishes.
What is the strangler-fig pattern, in plain terms?
It is a way of replacing an old system gradually rather than all at once, named after a fig that grows around a host tree and slowly takes its place. We put a facade in front of the legacy system so that whatever calls it does not know or care which implementation actually answers. Then we replace functionality one bounded piece at a time: we build the new version of a piece, route that piece’s traffic to it, verify it behaves the same as the old one, and retire the old code for that piece only once its replacement is proven in production. The new system grows around the old and takes over its work slice by slice, until what is left of the old system is small enough to switch off. The whole point is that there is always a working system in production. You are never in a state where everything is half-migrated and nothing works.
Our system has no tests and no documentation, and the people who built it have left. Can you still help?
Yes: that is one of the most common situations we are called into, and taking over exactly this kind of system is a real strength of ours. We do it the careful way rather than diving straight into changes. First we learn the system as it actually behaves, get it into version control and a reproducible build if it is not already, and stand it up somewhere we can safely experiment. Then we add observability so we can see what it really does in production instead of guessing, and we write down how it actually works as we learn. Crucially, we put automated tests around the parts that are both risky and important before we change anything: you do not need full test coverage to make change safe, you need coverage around what you are about to touch and what must never break. Only once those safety nets are in place do we start modernising, so the first change is one we can make confidently and reverse if we are wrong.
Is migrating really a security issue, or just a technical tidy-up?
For most legacy systems it is very much a security issue, and often the most urgent reason to act. An old system is typically running on a framework, language runtime and operating system that no longer receive security fixes, with libraries that have accumulated known, published vulnerabilities that were never patched. Those weaknesses are catalogued in public databases, which means they are known to attackers precisely, and automated scanning for unpatched systems is constant. A legacy system that has sat untouched is not safe because nothing has gone wrong yet: it is exposed, and the exposure grows with every new advisory published against the technology it is stuck on. We treat security as a first-order goal in a migration, inventorying the stack against advisories and sequencing the work so the most exploitable, most exposed parts are modernised first. For many organisations, closing those doors is the single most valuable outcome of the whole exercise.
What if the honest answer is that we do not need to migrate at all?
Then that is what we will tell you, and it is a genuine possible outcome of our assessment rather than a polite fiction. A stable, working legacy system that is secure, that is not blocking anything the business needs to do, and that is not costing much to keep running is not automatically a problem just because it is old. Migration carries cost and risk, and there is no virtue in taking those on to modernise something that is quietly doing its job. Our assessment is designed to tell you which situation you are actually in: whether the system is an exposure or a rising cost that warrants modernising, or whether it is fine left largely alone with sensible maintenance and patching. We are not in the business of manufacturing a large programme because that is what we sell; a straight answer, including "leave it alone", is what earns the kind of trust that keeps clients for years.
Thinking about Legacy Application Migration?
Tell us the problem in your own words, not in requirements. A senior engineer reads it and comes back with a straight view on whether Legacy Application Migration is the right answer here, or what would be.
- 01A senior engineer reads it. Not a form queue, and not an account manager.
- 02We reply either with questions or with a straight answer that we are not the right fit.
- 03If it looks like a fit, a technical call with the person who would actually run the delivery.
- 04Then scope, effort and risk in writing, before anyone signs anything.