Skip to main content
Guide

LegacySystemModernization:HowtoTellWhetherYourSystemActuallyNeedsaRewrite

The system still runs the business. It is also on a version nobody supports, two people understand it, and the quote you got for replacing it came with the phrase feature parity and a timeline in years. This page is written from your side of that quote. What modernization actually covers, why the quote defaulted to a rewrite, what a rewrite risks, how to tell whether your system can be moved in slices while it keeps running, and when a rewrite is honestly the right call.

An engineer reading a fifteen-year-old codebase on one screen beside an architecture diagram with a facade routing traffic between the old system and a new service.
|Sep 6, 2026|Legacy ModernizationEnterpriseArchitectureMigration

The short version

The system still runs the business. It is also on a version nobody supports, two people understand it, and the quote for replacing it came with the words feature parity and a timeline measured in years. You cannot tell whether that quote is the honest answer or the expensive one, and everyone you could ask sells the answer they give.

Here is the short version. Legacy system modernization is a spectrum, and a full rewrite is one end of it, not the whole of it. Most systems that still work can be modernized one capability at a time behind a facade, with the old system serving everything that has not moved yet and a way back at every step. The vendors that rank for this phrase almost all sell the platform that is their answer, which is why every one of them lands on replacement.

The rest of this page is the reading you do before you sign. Why the quote defaulted to a rewrite. What a rewrite actually risks, with the two most quoted failures named. A five-question test for whether your system can be moved in slices. The order those slices go in, and what happens to your data while two systems run. And the conditions under which a rewrite is honestly the right call, because sometimes it is, and a page that pretended otherwise would just be selling you something else.

What does legacy system modernization actually cover?

Everything from leaving the system alone and fixing one thing, through moving it to new hosting, replacing parts of it in place, and rewriting it from nothing. Modernization is the family. Rewrite is one member of it.

Start with what legacy means, because it is not age. Michael Feathers, in Working Effectively with Legacy Code, defined legacy code as code without tests. The point of the definition is that a system written last year with no tests is harder to change safely than a twenty-year-old system with good ones. What makes your system legacy is not the date on the copyright line. It is that nobody can change it and prove nothing else broke. That definition also tells you what the first modernization step usually is, and it is not a rewrite. It is writing tests that pin down the current behaviour, which Feathers called characterization tests, so that you can touch the code at all.

The vocabulary most quotes use, whether they say so or not, is the set of migration strategies AWS calls the 7 Rs. They are worth knowing because the word modernization hides which one you are being sold.

StrategyWhat changesWhat staysWhen it is the right one
RetireThe system is switched offNothingNobody has used it in months and no business value depends on it
RetainNothing yetEverythingIt works, the risk is low, or something else has to move first
RehostWhere it runsThe code, the data, the architectureThe hardware or the data centre is the problem, not the software
ReplatformThe runtime, the database engine, the packagingThe application logicThe version is unsupported but the logic is sound
RefactorThe structure, one part at a timeThe behaviour, and the live system throughoutThe architecture is what blocks change and the system must keep running
RepurchaseThe whole thing, for a product someone else maintainsYour data, after a migrationYour system does something a product now does better
RewriteEverything, from nothingThe requirements, if anyone wrote them downA specific condition in the honest-answer section below is true

Two things fall out of that table. The first is that AWS, which has every reason to want you moving workloads, tells its own large-migration customers not to refactor during a migration at all, because it is the most complex and costly strategy and should be done after the move, when the system is already running somewhere current. The second is that the word modernization appears in every row. When a vendor says your system needs modernizing, they have said nothing yet. When they say which row, the conversation starts.

Why did the quote you received default to a full rewrite?

For one of three reasons, and only one of them is about your system.

The first reason is the oldest one in the trade. Joel Spolsky wrote it down in April 2000 and nothing since has aged it: it is harder to read code than to write it. An engineer who opens a fifteen-year-old codebase sees a mess, because every codebase you did not write looks like a mess, and concludes it should be thrown away. What they cannot see from the outside is that the mess is where the bugs were fixed. Old code has been used. It has been tested by every customer who ever touched it. The strange branch that handles a negative quantity on a Tuesday is there because a customer once sent a negative quantity on a Tuesday, and the rewrite will find that out the same way the original did. A rewrite quote from someone who spent two days in the code is often a quote for not having to understand it.

The second reason is the vendor's own shape. Look at who ranks for this phrase. A low-code platform vendor writes that legacy systems should be rebuilt on low code. An analysis-tool vendor writes that you need an analysis tool. A hosting company writes that the answer is their cloud. An emulation vendor writes that the old hardware should be emulated. None of them is lying. Each of them has one product, so each of them has one answer, and the only version of your question they can profit from is the one their product solves. A consultancy that bills by the hour has the same shape from a different angle, because a three-year rewrite is more hours than a six-month displacement. We are not exempt from this. Geminate Solutions makes money from modernization work too, and the difference we can offer is not that we have no interest. It is that our engagement does not depend on which answer is right, so we can afford to give you the cheaper one when it is.

The third reason is real, and you should hold out for it. Sometimes there is a ceiling the current architecture cannot be extended past, and no amount of slicing changes that. A single-process system that has to become multi-region. A database design that cannot represent the business the company now runs. Source code that was lost with the contractor. The honest-answer section below lists these properly. The test for whether your vendor is in this third category is simple. Ask what specifically about your system makes incremental modernization impossible. A vendor with a real reason will name a file, a table or a constraint. A vendor without one will say it is best practice.

That question is the one to carry into every conversation about this, including the one with us, and it is why the diagnosis has to come before the quote rather than after it. Our enterprise engineering team does the diagnosis first, on your code, before anyone at Geminate Solutions says which row of that table you are in.

What does a big-bang rewrite actually risk?

Years with no shipping product, a spec that turns out to be the old system, and a system that ends up living longer because someone promised to replace it.

The first risk has a famous name. Netscape decided to rewrite its browser from scratch. When version 6.0 reached beta, version 4.0 had shipped nearly three years earlier and there had been no 5.0 in between. Three years in which the company that had defined the category had nothing new to sell while the competitor it was fighting shipped repeatedly. Spolsky called the decision the single worst strategic mistake a software company can make, and he was writing about it at the time, not with hindsight. A rewrite freezes the roadmap. Every feature your customers ask for during it is either built twice, once in the old system to keep them and once in the new one to have it, or not built at all. Our Angular team sees the small version of this constantly, where a company on an unsupported framework version is quoted every feature twice because it has to exist in both worlds.

The second risk is the phrase in your quote. Feature parity sounds like caution. Ian Cartwright, Rob Horn and James Lewis, writing on Martin Fowler's site about the legacy displacement work they have done, describe what it does in practice: even defining and agreeing what the current system does was a huge effort, and it led to a plan for one large big-bang cut-over release. That is the trap. Nobody knows everything the old system does, because the old system is the only complete specification of itself. So the team spends months writing down behaviour, misses the Tuesday branch, plans a single cut-over because parity means all or nothing, and the cut-over slips because parity is never reached. The same authors make a point that every rewrite quote ignores. Technology is at most half of the legacy problem. The ways of working, the organisation and the leadership around the system are the other half, and a new codebase inherits all of them untouched.

The third risk is quieter and it is the one we would put money on if we were betting. The promise of a replacement keeps the old system alive. In June 2019 the US Government Accountability Office examined 65 legacy systems across 24 federal agencies and named the ten most critical. They were between 8 and 51 years old. The Department of Education was running a 46-year-old system in COBOL, a language with few remaining skilled workers. The Treasury's was 51. And of the ten agencies responsible for those systems, three had no documented modernization plan at all, and only two had plans that met the basic elements of good practice. Those systems were not still running because nobody had proposed replacing them. They were still running because replacing them had been proposed, scoped as a rewrite, and found too big to start. A plan that cannot begin is a plan to keep the system forever.

None of this is a currency figure, and we are not going to put one here, because the number that matters is not the invoice. It is the length of time between signing and having something you can use. In a slice-by-slice modernization that time is weeks. In a rewrite it is the whole project.

Who does not need to modernize at all?

More companies than the vendors would like. If your system is stable, the runtime it sits on is still supported, the people who understand it are staying, the pain is confined to one or two places, and no auditor or customer has put a date on the platform, you should leave it alone and fix the two places.

That is not us being generous. It is AWS's own retain criteria, written for customers it would prefer to move: keep the system where it is when it was recently upgraded, when it has only a few internal users, when it depends on hardware with no equivalent elsewhere, when it needs a proper assessment before anyone touches it, or when something else has to move first. Retain is a strategy, not a failure to have one. A system that processes your orders correctly every day and costs you a small maintenance contract is an asset that a rewrite would turn into a liability with a delivery date.

There is a second group who need less than they think. If the pain is one thing, a report that takes an hour, an integration that broke when a partner changed their API, a login flow that a security review flagged, then that is one slice of work on the existing system, not a modernization programme. The strangler pattern described below is for systems where the whole architecture is the obstacle. When the obstacle is one module, you fix the module. Anyone who quotes you a platform for a module is answering a question you did not ask.

And a third group should not modernize because they should retire. A system nobody has logged into for a quarter, whose output nobody reads, is not legacy. It is finished. AWS's retire criteria are blunt about this: no inbound connections in ninety days, no business value in keeping it, and it can be switched off. Modernizing a system on its way out is the most expensive way to say goodbye to it.

If you are in any of those three groups, close this tab. You do not need us, and we will tell you the same thing if you send us the code.

How do you tell whether your system can be modernized without a rewrite?

Five questions. If you can answer yes to the first two and to at least two of the remaining three, the incremental path is open and the rewrite quote needs a better reason than the one it came with.

Can the requests going into the system be intercepted? Everything below depends on putting a facade between the users and the system, so that individual capabilities can be routed to new code one at a time. A web application, an API, a service behind a queue, a database that other systems read: all of these can be fronted. Microsoft's guidance on the strangler fig pattern names the case where they cannot as the first reason the pattern might not fit. A desktop application that talks to its own local files, or a batch job wired to a piece of hardware, may genuinely have no place to stand a facade. Most business systems do.

Do you have the source code, and the right to change it? The second reason on Microsoft's list. Displacing a system in slices means switching off the old implementation of each capability as the new one takes over, and that requires being able to edit the old system. If the source was lost with a contractor, or it is a vendor product you licence and cannot modify, the slicing has to happen at the boundary of the whole system rather than inside it. That is still not necessarily a rewrite, but it is a different and harder shape, and it belongs in the honest-answer section.

Is the pain isolated to particular modules? A system where the reporting is slow, the integrations are brittle and everything else is fine has a natural first slice. A system where every screen is entangled with every other through one shared table and one god object has to be understood before it can be cut, which is work, but it is assessment work, not rewriting work. The domain-driven design people call the cutting lines bounded contexts, and finding them is the first real task of any engagement.

Can you run two systems for months? The strangler pattern means the old system and the new services coexist, sometimes for a long time, with temporary plumbing between them. Fowler is direct that this plumbing is a cost and that the reduced risk and earlier value outweigh it. But it is a cost. If your organisation cannot tolerate two things being true at once for a while, or if a regulator requires the old system gone by a fixed date, the fourth item on Microsoft's not-suitable list applies.

Is there anyone left who knows it? Not to do the work. To answer questions about why the Tuesday branch exists. One person who understands the system, available for a few hours a week, shortens an assessment by months. If that person has already given notice, the assessment starts with characterization tests and archaeology, and it takes longer, but it is the same path.

One more, which is not a question about the system. Do you have tests? If the answer is no, you have Feathers' definition of legacy code and the first slice is not a feature at all. It is a safety net.

What does the incremental path look like, in order?

Pin the behaviour, put a facade in front, take the slice that hurts most, protect the boundary, cut over with a way back, remove the old slice, repeat. Every step leaves the system working and every step can be undone until the last one in each cycle.

  1. Write characterization tests around the capability you are about to move. Not tests of what the system should do. Tests of what it does, including the parts that look wrong. Feathers introduced these precisely for code that has no tests, and they are the difference between a refactor and a gamble. When the new slice passes the same tests as the old one, you have parity for that slice, proven rather than promised.
  2. Put a facade in front of the system. A proxy, a gateway, a routing layer, whatever fits the shape. At first it sends everything to the old system and changes nothing. Its job is to be the place where routing decisions live, so that from now on moving a capability is a routing change rather than a client change. Users keep using the interface they know and do not learn that a migration has started.
  3. Build the highest-friction capability as a new service. Highest friction, not easiest. The slice that costs the most in support hours or blocks the most roadmap is the one that proves the approach pays and buys the political room for the next one. Microsoft's guidance frames this as doing the high-return replacements first, and it is also the first moment the business gets something back.
  4. Put an anti-corruption layer between old and new. During the coexistence period the new service will need to call things that have not moved yet, and the old system will need to call things that have. Without a translating layer between them the new code ends up speaking the old system's dialect, and the modernization quietly imports what it was meant to remove. Microsoft names this explicitly, and it is the step that gets skipped when the budget is tight.
  5. Route the slice to the new service, keep the old path warm. The facade flips one capability. The old implementation is still there, so if the new one misbehaves the flip goes back in minutes. Canary the change if the traffic allows it. This is the step your board sees as the modernization, and it is the smallest one.
  6. Decommission the old slice once the new one has held. Remove the old code path, the old tables if they belong only to this capability, and the plumbing that connected them. This is the first irreversible step in the cycle, which is why it comes last in the cycle and only after the new slice has run in production long enough to trust.
  7. Repeat until nothing depends on the legacy system, then remove the facade. Or keep it, as Microsoft suggests, as an adapter for old clients while newer ones talk to the services directly. Either way, the old system is switched off when it is already doing nothing, which is a very different day from a cut-over.

The people who wrote the legacy displacement patterns have names for the tools in that list. Transitional architecture for the temporary plumbing. Event interception for catching the changes that flow into the old system so the new one can see them. Legacy mimic for making a new component look like the old one to the things that still depend on it. Divert the flow for moving a capability's traffic. You do not need to know the names. You need the vendor who quoted you to know them, and to have used them.

We have done this shape of work more than once. A single-tenant to multi-tenant migration is the same pattern applied to a data model rather than a codebase, and the article on it walks the slices for that case. Nothing that serves real traffic gets to a new architecture in one release. It gets there one slice at a time, or it does not get there.

What happens to your data while two systems run at once?

It stays in one place for as long as possible, moves one domain at a time with a sync running in both directions until the numbers match, and the old copy is deleted last. This is the section that decides whether a modernization is safe, and it is the section most quotes do not contain.

The reason it is hard is that a legacy system almost always has one central database that every part of the application reads and writes, with the business rules spread across the application code, the stored procedures and, in the worst cases, the triggers. You cannot move a capability to a new service and leave its data behind forever, because the new service would still be coupled to the old schema. You also cannot move the data first, because then the old system, which is still serving everything you have not migrated, would be reading stale copies.

Microsoft's strangler fig guidance gives the sequence for a shared database, and it is the one we follow. First, the new service reads and writes the legacy database directly. One source of truth, no sync, and the new code is live against real data from day one. Second, when the domain is ready, its tables and history are loaded into a new database with an initial extract, transform and load, and from then on a change data capture process keeps the new database in step with every write the old system still makes. Both databases exist. The old system writes to the old one, the new service writes to the new one, and the sync carries the changes across. Third, and only after consistency between the two has been validated, the new database becomes the system of record for that domain, the new service stops touching the old tables, and the old tables, stored procedures and sync jobs are removed.

The ordering matters because of what it does to rollback. Right up to the removal step, going back is cheap: point the routing at the old system, and the old tables are still there with the sync still feeding them. After the removal step, going back means restoring those objects and replaying every change since, which Microsoft describes plainly as significantly more effort and risk. So the removal is treated as a deliberate final act for each domain, done only when the new slice has earned it. Anyone who plans to drop the old tables on cut-over day has planned to have no way back.

Two questions to ask about the data in any quote you receive. Where are the business rules, in the application or in the database, because rules in stored procedures have to be found and moved and the quote should say how. And what is the validation step, because validated consistency means someone compared the two databases and can show you the result, not that the sync reported no errors.

When is a rewrite the honest answer?

When one of a short list of conditions is true, and you should be able to see which one from your side of the table.

AWS's own criteria for choosing refactor or re-architect, which is the strategy closest to a rewrite in the 7 Rs, are a fair list. The system can no longer meet the demand the business puts on it because of a limit in how it was built, not in how it is hosted. The monolith is already the thing stopping you shipping. Nobody knows how to maintain it, or the source is unavailable. It cannot be tested and coverage is so low that every change is a risk. Microsoft adds the case at the other end of the scale: the system is small enough that replacing it whole is simpler than routing around it, or the original must be fully decommissioned quickly and there is no time for coexistence.

Notice what is on that list and what is not. On it: a real architectural ceiling, lost source, a system too small to bother slicing, a hard deadline for switching the old one off. Not on it: the code is old, the code is ugly, the framework is out of fashion, the vendor does not know the language, or the vendor's platform is not what it was written in. Those are the reasons in most rewrite quotes, and none of them is a reason.

Even inside the honest list, the rewrite is usually not a big bang. A system that has to become a different architecture can still be displaced capability by capability, with the new architecture growing behind the same facade. Lost source can be handled by treating the whole old system as one black-box slice, fronting it, and building around it until it does nothing, which is slower than editing it but faster than freezing the roadmap for three years. The honest rewrite is a rewrite of the thing that has to change, delivered in the order the business needs it, with the old system serving until each part is replaced. It is very rarely a new repository, a two-year plan and a cut-over weekend.

When it is genuinely the whole thing, we will say so. The sentence is easy to say when it is true, and Geminate Solutions has no platform to protect by avoiding it. What we will not do is arrive at that sentence without having read the code, and we will not quote it with a single cut-over date.

What should you ask before you sign off a rewrite?

Six questions, and every one of them has a specific answer if the vendor has done the work. Vague answers to any of them are the answer.

  1. What specifically about this system makes incremental modernization not viable? The answer should name a constraint: requests that cannot be intercepted, source you do not have, a data model that cannot be split. If the answer is best practice, or the framework is old, the rewrite has not been justified.
  2. Which of the 7 Rs is this, and why not the one before it? A vendor who cannot place their own proposal on that table has not considered the alternatives. Ask why replatform is not enough before you accept refactor, and why refactor is not enough before you accept rewrite.
  3. What does the business get, and when, before the end? A slice-by-slice plan has a first delivery in weeks and a working, reversible state after every step. A plan whose first usable output is the final cut-over is a big bang wearing an agile vocabulary.
  4. How will you know the new system does what the old one does? Characterization tests are the honest answer. A requirements document written by interviewing users is the feature parity trap, because the users do not know about the Tuesday branch either.
  5. What happens to the data, in order, and what is the rollback at each step? You want to hear the sequence from the data section above, or an equivalent, with the removal of old tables named as the last, deliberate step. If the plan drops the old schema on cut-over day, ask what happens on cut-over night.
  6. What happens to the features we need during the project? Built once, in the new slices as they land, is the right answer. Built twice, or frozen until launch, is the Netscape answer.

Ask us the same six. The engagement section below is our answer to them, and if it does not satisfy you on any one, that is the one to push on.

How does Geminate Solutions run a legacy modernization engagement?

Assessment first, on your actual code. Then the least disruptive row of the table that meets the requirement, delivered in slices, with the live system serving throughout and you owning every line from the first commit.

The assessment is where the rewrite question gets answered, and it is answered before any build is scoped. A senior engineer reads the codebase and the schema, finds where the business rules actually live, maps the capabilities and the dependencies between them, and checks the five questions from this page against what is there. The output is a written read: which row of the strategy table you are in and why, which slice goes first and why that one, where the data is going to be hard, and what the honest timeline looks like. If the read says retain and fix two modules, that is what it says, and the engagement is those two modules.

The build follows the order in the incremental section. Characterization tests before the first change. A facade before the first slice. The highest-friction capability first, so you see a return before you see a bill for the second one. An anti-corruption layer at the boundary. Routing flips you can reverse. Old code removed only when the new code has held. We migrate AngularJS applications this way onto supported Angular versions, with the app shipping the whole way. The scale we operate at is real and you can hold us to it: an EdTech platform at 250,000+ daily users, an exam platform at 10M+ requests a minute, Pixytan tracking 30,000+ vehicles, 50+ products shipped, Top Rated Plus on Upwork at 4.9. None of that is a rebuild pitch. It is the level at which a system cannot be allowed to stop, which is the level this discipline exists for.

What you own. The code, the infrastructure credentials and the documentation, from the first commit, in your repositories. We are a software and product development partner, not a staffing desk, and not a platform vendor with one answer. The team that does the assessment is the team that does the build, and if the honest answer is that you do not need us, the read says that too. Our enterprise software page covers the engagement models, and the custom software development guide is the read for the case where the answer turns out to be a new product rather than a modernized one.

The first step is a free written modernization read. Send us access to the repository, or a description of the system and the quote you were given if access is not possible yet. Within 48 hours a senior engineer sends back which strategy your system actually needs, whether the rewrite you were quoted is justified by anything in the code, which slice we would take first, and where the data will be difficult. It is yours whether or not we ever speak again.

Frequently Asked Questions

What is legacy system modernization?

Legacy system modernization is the work of bringing an old system that still runs a business up to current requirements for support, security, integration and change, without losing the logic that makes it work. It is a spectrum. At one end is retaining the system and fixing the one thing that hurts. In the middle are rehosting, replatforming and refactoring in slices while the system keeps serving. At the far end is a full rewrite. Michael Feathers defined legacy code as code without tests, which is why the first step in most modernization work is putting characterization tests around the behaviour you cannot afford to change.

Is it better to rewrite or refactor a legacy system?

Refactor in slices unless a specific condition forces a rewrite. Joel Spolsky called rewriting from scratch the single worst strategic mistake a software company can make, because old code has been used and tested and its bugs have been found and fixed. A rewrite is the honest answer when the source is unavailable, when nobody can maintain the system and it cannot be put under test, when the architecture has a hard ceiling the business has already hit, or when the system is small enough that replacing it whole is simpler than routing around it. If none of those is true of your system, the rewrite quote deserves a second opinion.

How does the strangler fig pattern modernize a legacy system?

A facade is placed in front of the legacy system so every request passes through it. At first the facade routes everything to the old system. One capability at a time is rebuilt as a new service, and the facade routes that capability's requests to the new code while everything else still goes to the old. Users keep using the same interface and do not know a migration is in progress. When nothing depends on the legacy system any more it is decommissioned and the facade is removed. Microsoft's architecture guidance says the pattern is not suitable when requests cannot be intercepted, when you cannot access the legacy source code, when the system is small enough that replacing it is simple, or when the old system must be shut down quickly.

What happens to the data while the old and new systems run at the same time?

The new service starts by reading and writing the legacy database directly, so there is one source of truth. When a domain is ready to move, its tables are loaded into a new database with an initial extract and load, then kept in step with change data capture while both databases exist. Consistency is validated between them before anything cuts over. Only after the new database is confirmed as the system of record are the old tables, stored procedures and sync jobs removed, and rollback is cheap right up to that step and expensive after it. This is the sequence in Microsoft's own strangler fig database example, and it is the part most modernization quotes leave out.

How long does legacy system modernization take?

It depends on how many capabilities the system has, how tangled the data is, and how much of the old behaviour is documented or tested. The honest answer for an incremental engagement is that the first slice ships in weeks and the whole system is displaced over months, with the live system up throughout and a working, reversible state at the end of every slice. A big-bang rewrite is quoted in years and delivers nothing usable until the end. Netscape went nearly three years without a shipping browser after choosing to rewrite. Geminate Solutions scopes the timeline from an assessment of your actual codebase, not from a template.

YK
Written by

CEO and co-founder of Geminate Solutions, a software and product development partner. He has led teams shipping custom web apps, mobile apps, SaaS platforms, and AI products that serve over 250,000 daily active users.

Free modernization read

Send us the system and the quote. We will tell you whether the rewrite is justified.

A senior engineer reads your codebase and schema, places your system on the strategy table, says whether anything in the code justifies the rewrite you were quoted, names the first slice we would take, and shows where the data will be hard. No pitch, no commitment, and if the honest answer is that you should leave it alone, the read says so.

  • Which of the 7 Rs your system actually needs, and why not the one before it
  • Whether the rewrite quote is justified by anything in the code
  • The first slice we would take, and what it returns to the business
  • Where the data is going to be difficult, and the rollback at each step

Get your free modernization read

Drop a link to the repository or the system and your work email. We reply within 48 hours.

Reply in 48 hours. Free, no pitch, no commitment. By submitting, you agree we may use your details to reply, under our legitimate interest and stored via EmailJS. We never sell your data. Privacy Policy.

FAQ

Frequently asked questions

What is legacy system modernization?
Legacy system modernization is the work of bringing an old system that still runs a business up to current requirements for support, security, integration and change, without losing the logic that makes it work. It is a spectrum. At one end is retaining the system and fixing the one thing that hurts. In the middle are rehosting, replatforming and refactoring in slices while the system keeps serving. At the far end is a full rewrite. Michael Feathers defined legacy code as code without tests, which is why the first step in most modernization work is putting characterization tests around the behaviour you cannot afford to change.
Is it better to rewrite or refactor a legacy system?
Refactor in slices unless a specific condition forces a rewrite. Joel Spolsky called rewriting from scratch the single worst strategic mistake a software company can make, because old code has been used and tested and its bugs have been found and fixed. A rewrite is the honest answer when the source is unavailable, when nobody can maintain the system and it cannot be put under test, when the architecture has a hard ceiling the business has already hit, or when the system is small enough that replacing it whole is simpler than routing around it. If none of those is true of your system, the rewrite quote deserves a second opinion.
How does the strangler fig pattern modernize a legacy system?
A facade is placed in front of the legacy system so every request passes through it. At first the facade routes everything to the old system. One capability at a time is rebuilt as a new service, and the facade routes that capability's requests to the new code while everything else still goes to the old. Users keep using the same interface and do not know a migration is in progress. When nothing depends on the legacy system any more it is decommissioned and the facade is removed. Microsoft's architecture guidance says the pattern is not suitable when requests cannot be intercepted, when you cannot access the legacy source code, when the system is small enough that replacing it is simple, or when the old system must be shut down quickly.
What happens to the data while the old and new systems run at the same time?
The new service starts by reading and writing the legacy database directly, so there is one source of truth. When a domain is ready to move, its tables are loaded into a new database with an initial extract and load, then kept in step with change data capture while both databases exist. Consistency is validated between them before anything cuts over. Only after the new database is confirmed as the system of record are the old tables, stored procedures and sync jobs removed, and rollback is cheap right up to that step and expensive after it. This is the sequence in Microsoft's own strangler fig database example, and it is the part most modernization quotes leave out.
How long does legacy system modernization take?
It depends on how many capabilities the system has, how tangled the data is, and how much of the old behaviour is documented or tested. The honest answer for an incremental engagement is that the first slice ships in weeks and the whole system is displaced over months, with the live system up throughout and a working, reversible state at the end of every slice. A big-bang rewrite is quoted in years and delivers nothing usable until the end. Netscape went nearly three years without a shipping browser after choosing to rewrite. Geminate Solutions scopes the timeline from an assessment of your actual codebase, not from a template.
FREE WEBSITE REVIEW

Get a free 24-hour review of your website

Send us your website link on WhatsApp. Within 24 hours we tell you exactly what is costing you customers and what we would fix first. No obligation and no sales script.

Send my website for review

4.9 rated · 50+ products shipped · 250K+ daily users served

GET STARTED

Already built something, and it is starting to break?

Most teams that reach us have a working product and a growing list of things that scare them. We read the code first and tell you what actually needs fixing, including the parts that do not. Rebuilding from scratch is rarely the honest answer.

Related Articles