Four applications. Same company. One has an expired database, one runs a report nobody reads, one is a vendor package due for SaaS replacement next year, and one is a monolith blocking every product release.
A vendor proposes microservices for all four.
That is not legacy application modernization. It is one delivery motion looking for four invoices.
Here is the treatment those workloads probably deserve before anyone sees their source code:
| Workload | Evidence that matters | Likely treatment | First proof |
|---|---|---|---|
| Claims app on SQL Server 2016 | business-critical; database support ended July 14, 2026; application behavior is stable | replatform the database or use eligible ESUs as a dated bridge to an upgrade | compatibility test plus a restored production copy on the supported target |
| Internal reporting app | twelve monthly users two years ago; no inbound traffic now; outputs duplicated in BI | retire | owner sign-off, dependency check, archived data, shutdown rehearsal |
| Customized vendor ERP | stable; vendor SaaS replacement contracted for next year | retain, then replace | integration and data-export test against the replacement |
| Release-blocking monolith | active roadmap; one deployment train; components scale and fail together | refactor or rearchitect in slices | extract one bounded capability behind the existing interface |
This is a composite example, not a client case study. Its point is simple: age does not choose the strategy. The business job, support exposure, dependencies, and change demand do.
Microsoft’s current Cloud Adoption Framework lists eight treatments for a workload: retire, retain, rehost, replatform, refactor, rearchitect, rebuild, or replace. It starts with the business driver and the gap between today’s workload and the outcome the business needs. AWS offers a similar menu in its migration strategy guidance.
A useful modernization assessment turns those menus into one decision per application. Nothing is gained by calling the whole portfolio “legacy” and pointing it at one target diagram.
Workload one: clear support exposure without pretending a move is an upgrade
SQL Server 2016 left extended support on July 14, 2026. Microsoft’s lifecycle record now lists three annual Extended Security Updates releases through July 17, 2029.
Rehosting an unchanged SQL Server 2016 workload does not make the product supported again. Microsoft’s end-of-support guidance separates the options: upgrade to a supported SQL Server release, migrate to an evergreen managed service such as Azure SQL, or use eligible Extended Security Updates as a bridge. Moving the same unsupported binaries to a different virtual machine is still moving unsupported binaries unless the destination carries a valid ESU benefit.
That distinction changes the first proof. The team needs a restored copy of production data, a compatibility pass on queries and application drivers, representative performance tests, and a rehearsed rollback. The first milestone is not “cloud account created.” It is “the application behaves correctly on a supported target, and we can get back if it does not.”
A deadline may justify the least disruptive supported move first. It does not justify redesigning the application under the same cutover. AWS explicitly calls refactoring the most complex migration strategy and advises large migrations to rehost, relocate, or replatform first, then modernize afterward when possible. Fewer simultaneous variables make failures easier to isolate.
Workload two: retirement is engineering work too
The reporting app has no active audience and duplicates data already available elsewhere. It should not be containerized. It should be switched off.
That still needs proof. Check scheduled jobs, service accounts, inbound traffic, exported files, downstream reports, retention rules, and the person who signs the shutdown. Archive data in a format the business can read without resurrecting the app. Disable it in a reversible window before deleting anything.
AWS defines retire as decommissioning or archiving an application that no longer has business value. Its guidance also uses runtime evidence to spot zombie or idle applications. That is why a modernization inventory needs traffic and utilization, not just repository names and server versions.
Retirement often produces the fastest measurable return in a portfolio: license gone, server gone, monitoring gone, vulnerability surface gone. It is also the treatment vendors under-recommend because there is less code to bill. Put retirement candidates in the assessment anyway.
Workload three: retain can be a deliberate answer
The ERP is stable, and a contracted SaaS replacement arrives next year. Refactoring the current package now would create work with no payback window.
Retain does not mean forget. The decision record needs a review date, a support and security posture, the replacement dependency, and a fallback if the SaaS schedule slips. Test data exports and critical integrations early because those are the parts most likely to turn a planned replacement into an emergency extension.
Microsoft describes retain as appropriate when a workload is stable, compliant, and meeting business needs with no near-term driver to move. AWS includes similar reasons: unresolved dependencies, recent investment, compliance constraints, or a planned SaaS replacement.
A dated retain decision is strategy. An undated one is drift.
Workload four: use incremental replacement where the business needs change
The monolith is different. Its age is secondary. It blocks the roadmap. Three teams queue behind one deployment, a failure in one component threatens the whole release, and scaling demand differs by function. Those are business and architectural reasons to change code.
Microsoft maps modularization, service decomposition, and component-specific scaling needs to rearchitecture. That does not mean “split everything into microservices.” The first question is whether the code and data have a boundary that can move independently.
For a usable boundary, the Strangler Fig Pattern is a strong default. A facade intercepts requests and routes them to either the legacy application or a new service. The team moves one capability at a time. Users keep the same interface while responsibility shifts behind it.
The first slice should prove the hard part, not the easiest screen to demo. Pick one bounded capability with real traffic, a meaningful dependency, and behavior the team can compare. Define these conditions before work begins:
- expected business or operational outcome;
- behavior that must remain identical;
- data reconciliation rule and acceptable variance;
- rollback trigger and maximum rollback time;
- legacy retirement condition after the new path holds.
Microsoft’s cautions deserve as much attention as the pattern diagram. The facade can become a bottleneck or single point of failure. Old and new systems may need concurrent access to shared data. Cross-system calls may need an anti-corruption layer so the new design does not inherit every legacy convention. The facade is transitional architecture, not a permanent trophy.
The shared database usually decides whether the boundary is real. Microsoft’s example phases a domain database out of a monolith using an initial ETL load, change data capture for synchronization, and consistency checks before cutover. Rollback becomes much harder after old tables and procedures are removed. Treat deletion as its own approval gate.
The decision record behind all four calls
The four treatments differ, but the evidence sheet is the same. Procurement should expect one completed record per workload, not one paragraph for the estate.
| Field | What belongs in it | Bad answer |
|---|---|---|
| Business job | owner, users, critical workflow, measurable outcome | ”important internal app” |
| Support exposure | OS, runtime, database, vendor contract, exact dates | ”old stack” |
| Dependencies | callers, APIs, batch jobs, identity, reports, file drops | a diagram based only on code imports |
| Data | system of record, regulated fields, retention, reconciliation | ”shared database” with no table ownership |
| Code health | source access, reproducible build, tests, deploy path | language and framework names only |
| Runtime evidence | traffic, utilization, incidents, latency, run cost | last year’s CMDB entry |
| Change demand | roadmap blocked, release lead time, scaling or hiring limit | ”needs modernization” |
| Treatment | chosen strategy, rejected options, confidence, unknowns | one strategy copied down every row |
| First proof | smallest reversible test of the decision | disconnected proof of concept |
| Exit | success metric, rollback trigger, retirement condition | ”phase two later” |
Unknowns stay visible. If nobody knows who owns a database table, write that down and define the test that resolves it. Hiding it under “shared” merely moves discovery to cutover, where it costs more.
Characterization tests recover the specification
Old applications often have exact behavior and poor documentation. Users know the Tuesday export rounds one field differently. Finance knows which adjustment appears in the next period. A replacement team discovers those rules as production defects unless it captures current behavior before changing it.
Characterization tests do not declare the old behavior correct. They record what exists so business owners can choose what to preserve and what to fix.
Build the safety net around the boundaries the project will disturb:
- contract tests for APIs, files, and events;
- golden-master comparisons for reports and transformations;
- reconciliation queries for totals, duplicates, and referential integrity;
- replay tests from scrubbed production traffic;
- cutover checks operations can run without a developer;
- a rollback rehearsal measured with a clock.
Negative cases carry more signal than the happy path. What happens when the source file arrives twice? When the new service times out after the legacy system committed? When synchronization pauses during cutover? Modernization exposes partial failures the monolith used to hide.
A 90-day acceptance plan for the first slice
Do not treat this as a universal delivery promise. Mainframe portfolios and tightly regulated systems can take far longer. Use it as a procurement acceptance plan for one substantial application: by day 90, what evidence should exist if the first slice is small enough and the dependencies cooperate?
| Window | Work | Evidence procurement can accept |
|---|---|---|
| Days 1 to 15 | owner interviews, runtime observation, dependency tracing, support-date check | signed workload decision, dependency map, visible unknowns |
| Days 16 to 30 | characterization tests, target options, first-slice and rollback design | passing baseline tests, approved slice, measurable outcome |
| Days 31 to 60 | build the slice, wire observability, establish data sync or translation | production-like test with failure modes exercised |
| Days 61 to 75 | shadow or limited traffic, reconcile outputs, rehearse cutover | variance inside agreed limit; timed rollback completed |
| Days 76 to 90 | move traffic, observe, then approve or defer legacy retirement | stable new path and explicit next decision |
The retirement decision may be “not yet.” That is acceptable when evidence supports it. What is not acceptable is letting parallel run become permanent by omission. A missing retirement condition raises the risk of two systems, two security surfaces, and a synchronization job nobody owns.
Procurement questions that expose a thin proposal
Ask these before scoring the vendor deck:
- Show one workload where you recommended retire or retain instead of paid engineering. What evidence drove the call?
- Which treatment did you reject for our first application, and why?
- How will you discover runtime dependencies that do not appear in source code?
- What current behavior will be captured before the first code change?
- What is the smallest slice that tests our hardest dependency?
- Who can call rollback, what data must be reconciled, and how long should rollback take?
- Which old component can be retired after slice one, and what evidence closes that gate?
- How will you measure business value beyond servers moved or code converted?
- What temporary architecture will the migration add, and who removes it?
- Which unknown could invalidate the estimate?
A strong vendor can answer with artifacts and owners. A weak one answers with methodology names.
Review one workload before buying a portfolio program
Our legacy application modernization practice starts with a focused assessment rather than a portfolio-wide rewrite commitment. Architecture and client-facing leadership sit in Austin, with implementation capacity from Bangalore and Mohali on overlapping US hours. The recommendation still has to survive review by the people who operate the application.
Start smaller than the estate. Complete one workload decision record using the table above: business owner, support exposure, dependencies, data, current behavior, change demand, candidate treatment, rejected options, and first reversible proof. Send us that record, even if half the fields say unknown. We will review the decision before proposing the build. Sometimes the answer is refactor. Sometimes it is an ESU bridge, SaaS replacement, or a shutdown calendar. The reason belongs in writing either way.