Legacy systems create a particular kind of impatience.

The team knows the architecture is difficult. Releases are slow. Dependencies are old. Tests are weak. Infrastructure is expensive. Every change seems to touch something unexpected.

Eventually someone proposes the emotionally satisfying solution:

Rewrite it.

Sometimes that is correct.

Often it is a reaction to accumulated frustration rather than a strategy.

Modernization does not require preserving everything that exists. It requires understanding which constraints create the greatest business and engineering cost, then changing the system in a way that improves those constraints without creating unacceptable transition risk.

For many critical systems, that leads to incremental replacement rather than a big-bang cutover.

Rewrite Bias Comes From Seeing the Old System's Pain Clearly

Teams know the weaknesses of the current system because they live with them every day.

They do not know the weaknesses of the replacement because it does not exist yet.

That asymmetry creates rewrite bias.

The new system appears clean because its hidden requirements, operational edge cases and integration history have not been rediscovered.

Large existing systems often contain behavior that nobody documented but somebody depends on. A rewrite reveals these dependencies late because production behavior has become part of the specification.

Martin Fowler's Strangler Fig metaphor emerged from this reality. Rather than replacing a critical system in one cutover, new capability can grow around the old system while functionality moves gradually into the new structure.

The value is not the botanical metaphor. It is the risk model.

Start With Outcomes, Not Technology

"Move to microservices" is not a modernization outcome.

"Move to Kubernetes" is not a modernization outcome.

"Rewrite in a newer language" is not a modernization outcome.

Those may be implementation choices. Modernization should begin with constraints the organization needs to change.

Examples:

  • releases take six weeks because every component must deploy together;
  • a single database prevents independent scaling;
  • unsupported dependencies create security exposure;
  • manual deployment makes rollback unreliable;
  • one integration blocks product change;
  • production incidents cannot be diagnosed because observability is insufficient;
  • infrastructure cost is dominated by overprovisioned workloads;
  • a critical workflow cannot evolve because business rules are embedded across the UI and database.

The modernization program should define target capabilities that respond to these constraints.

Otherwise, the organization can replace the technology and preserve the problem.

Create Seams Before Replacing Behavior

Incremental modernization requires places where old and new behavior can coexist.

Those seams may be:

  • API gateways;
  • facades;
  • event streams;
  • abstraction layers;
  • database views;
  • anti-corruption layers;
  • routing rules;
  • adapters.

The seam creates a controllable boundary.

Consumer
   ↓
Stable boundary
  ↙       ↘
Legacy    New capability

Traffic or behavior can move gradually instead of requiring a single cutover.

AWS Prescriptive Guidance describes the Strangler Fig pattern as a way to incrementally migrate functionality while reducing transformation risk and business disruption. It also notes a critical trade-off: the coexistence mechanism can itself become complex or introduce bottlenecks.

Incremental modernization reduces one category of risk while creating temporary complexity.

That trade-off should be explicit.

Testing Is Modernization Infrastructure

Teams often treat tests as something to improve after the architecture becomes cleaner.

That reverses the dependency.

If the organization cannot tell whether old and new behavior are equivalent where they need to be, migration becomes dangerous.

Tests create confidence to introduce seams, redirect traffic, change dependencies and remove old paths.

The most useful coverage is not necessarily broad unit-test percentage. Modernization often needs:

  • characterization tests for existing behavior;
  • contract tests around integrations;
  • end-to-end coverage for critical flows;
  • migration validation for data;
  • production smoke tests;
  • canary signals;
  • reconciliation between old and new results.

Testing makes incremental replacement observable.

Without it, every step becomes a mini big bang.

Observability Enables Progressive Change

Incremental modernization creates a period where multiple implementations coexist.

The organization needs to know which path handled a request, how each path performed, where errors occurred and whether outcomes differ.

That requires observability designed around the migration.

Useful signals include:

  • traffic percentage by implementation;
  • error rate by route;
  • latency by route;
  • data reconciliation differences;
  • fallback frequency;
  • dependency failures;
  • resource cost;
  • user-visible outcome metrics.

Observability is not only an operational concern. It is how the program proves whether the target state is actually improving the system.

Data Is Usually the Hardest Boundary

Application code can often be routed incrementally. Data is less cooperative.

Legacy systems may share tables across domains, encode business rules in stored procedures, rely on undocumented identifiers or allow multiple components to mutate the same records.

Modernizing behavior without clarifying data ownership can create a distributed architecture around a shared legacy data model. The organization gains deployment complexity without gaining independence.

Data modernization questions include:

  • Which system is authoritative during coexistence?
  • Can both old and new write?
  • How are conflicts resolved?
  • What historical data must move?
  • How is migration verified?
  • Can the migration be replayed?
  • What happens during rollback?
  • Which data can remain in place?

A good modernization plan often treats data migration as its own product and operational problem.

Cloud Migration Is Not Automatically Modernization

Moving a legacy workload from a data center to cloud infrastructure may improve infrastructure management without changing application constraints.

Likewise, containerizing an application can improve deployment consistency without making the application modular.

Those changes may still be valuable.

The mistake is confusing platform movement with capability improvement.

A modernization program should state what each change is expected to improve:

ChangePossible benefitWhat it may not solve
Rehost to clouddata-center exit, provisioning flexibilityapplication coupling
Containerizedeployment consistencydomain boundaries
Upgrade runtimesupportability, securityrelease coupling
Modularize codechange isolationdeployment independence
Extract serviceownership, scaling, release isolationpoor domain model
Replace databaseperformance or operational benefitunclear data ownership

Technology is useful when it changes the constraint that matters.

Parallel Systems Have a Cost

Incremental modernization is not free.

For a period, the organization may operate:

  • two code paths;
  • duplicated infrastructure;
  • synchronization processes;
  • compatibility layers;
  • extra monitoring;
  • migration tooling;
  • temporary team structures.

The transition architecture can become permanent if the program loses momentum.

A strangler pattern without elimination becomes accumulation.

Every incremental modernization plan therefore needs exit conditions:

  • What old capability will be removed?
  • What dependency disappears?
  • Which data source stops being authoritative?
  • Which temporary adapter can be deleted?
  • What proves that the old path is no longer required?

Modernization should reduce structural complexity over time, not merely add new technology beside old technology.

When a Rewrite Is Justified

"Never rewrite" is as simplistic as "rewrite everything."

A rewrite may be rational when:

  • the system is small enough to replace with bounded risk;
  • the existing architecture prevents meaningful incremental seams;
  • the old platform is unsupported and creates urgent exposure;
  • the product itself has changed so much that preserving legacy behavior has little value;
  • data can be migrated safely;
  • operational requirements are well understood;
  • the organization can sustain parallel business change while replacement occurs.

Even then, the team should be precise about cutover, rollback, data migration, validation and business continuity.

The decision is not ideological. It is economic and operational.

Modernization Should Change the Cost of Future Change

The purpose of modernization is not to make a diagram look contemporary.

It is to improve the organization's ability to evolve.

That may mean faster releases, safer deployments, clearer ownership, lower incident risk, better security, reduced dependency cost or more predictable scaling.

These outcomes connect directly to Technical Debt Is a Business Constraint. Debt matters when it changes the feasibility or economics of future decisions.

A useful modernization roadmap prioritizes changes that improve future change.

Evolve the System in Visible Steps

A strong incremental modernization sequence often looks like:

Understand constraints
  ↓
Define target capabilities
  ↓
Create a seam
  ↓
Move one bounded behavior
  ↓
Validate in production
  ↓
Migrate data or ownership as needed
  ↓
Remove the old path
  ↓
Repeat

The sequence creates evidence as it moves.

That is the advantage over a big-bang rewrite. The organization does not need to wait until the end to discover whether the strategy works.

Modernization remains difficult. Existing systems carry history, dependency and organizational structure. Incremental approaches do not eliminate that complexity.

They make the complexity visible in smaller decisions.

A modernization program succeeds when each step removes a meaningful constraint and leaves the organization more capable of making the next change.

The objective is not to escape the legacy system in one dramatic event.

It is to evolve the system until the constraints that justified modernization no longer dominate the business.

References

  1. Martin Fowler. Strangler Fig. 2024. https://martinfowler.com/bliki/StranglerFigApplication.html
  2. Martin Fowler. Original Strangler Fig Application. 2004. https://martinfowler.com/bliki/OriginalStranglerFigApplication.html
  3. AWS. Strangler fig pattern. AWS Prescriptive Guidance. https://docs.aws.amazon.com/prescriptive-guidance/latest/cloud-design-patterns/strangler-fig.html
  4. AWS. Branch by abstraction pattern. AWS Prescriptive Guidance. https://docs.aws.amazon.com/prescriptive-guidance/latest/modernization-decomposing-monoliths/branch-by-abstraction.html
← All Insights