Modernize the system that still runs payroll, one slice at a time.
The system has run for longer than most of the team has worked there, the documentation is the code, and the person who understood the batch schedule has moved on. We modernize systems like that in slices, with old and new running side by side until the numbers match.
Legacy databaseDB2 · Oracle · SQL ServerNew data storemanaged databaseOutput reconciliationparallel run diffs
Microsoft Entra IDOktaTerraformSalesforce
in short·20-second read
Legacy modernization replaces or restructures aging applications without stopping the business that depends on them.
Cohash assesses the code and its dependencies, extracts business rules, and modernizes in slices using the strangler fig pattern, so old and new systems run in parallel until outputs match. We handle .NET Framework and Java upgrades, mainframe workloads with tools such as AWS Transform for mainframe, and replace shared service accounts with modern identity.
you probably need this if
Business rules live only in code that a few people can still read.
It's on .NET Framework or an old version of Java, and upgrades keep slipping.
A rewrite was tried once and abandoned because the new system never matched the old outputs.
From the first call to a setup your own team can run.
Here's what usually prompts a call about your Legacy Modernization, what we do about it and in which order, and where you end up.
01 · where it hurts02 · what we change03 · how it runs04 · where you end up
incident board · legacy modernization3 open
openBusiness rules live only in code that a few people can still read.
recurringIt's on .NET Framework or an old version of Java, and upgrades keep slipping.
blockedA rewrite was tried once and abandoned because the new system never matched the old outputs.
exposure
Assessment and business rule…Strangler fig migrationRuntime and framework upgradesMainframe modernizationData migration and reconciliationIdentity cleanup
startrehearsehandover
Assess
Choose a path per component
Modernize in slices
Decommission
we are here
ready to hand over
The posting rules are written down and traced to code, and what the experts knew now…
The OS deadline gets met without waiting on the rewrite.
Every difference has an explanation and a decision.
Application assessment with dependency map
chapter 01 · where it hurts
Why teams reach out
Business rules live only in code that a few people can still read.
It's on .NET Framework or an old version of Java, and upgrades keep slipping.
A rewrite was tried once and abandoned because the new system never matched the old outputs.
chapter 02 · what we change
How we solve it
Assessment and business rule extraction
Strangler fig migration
Runtime and framework upgrades
Mainframe modernization
Data migration and reconciliation
Identity cleanup
chapter 03 · how it runs
Our approach
Assess
Choose a path per component
Modernize in slices
Decommission
chapter 04 · where you end up
What changes
The posting rules are written down and traced to code, and what the experts knew now lives in tests.
The OS deadline gets met without waiting on the rewrite.
Every difference has an explanation and a decision.
Application assessment with dependency map
what we do
Where we spend the hours
6 areas of work, each one done by an engineer who has run it in production.
We read the code, map dependencies and talk to the people who still remember why a rule exists. Every rule gets written down with a pointer to where it lives in the code.
Put a routing layer in front and send one function at a time to the new service. Everything else stays on the old system. Keep each slice small enough to roll back.
.NET Framework to .NET 10, older Java to a current LTS release, and app servers off Windows Server 2016 before its extended support ends in January 2027.
AWS Transform for mainframe for dependency analysis, business rule extraction, code generation and test generation. We review its output, write the equivalence tests and run parallel batches against production data.
Data moves and gets reconciled during parallel runs. Before any cutover, reports have to show record counts and totals matching.
Old applications often check passwords against their own tables and call other systems with a shared service account. We move users to SSO over OIDC or SAML and give each service its own identity.
capability 01 / 06in production
Assessment and business rule extraction
We read the code, map dependencies and talk to the people who still remember why a rule exists. Every rule gets written down with a pointer to where it lives in the code.
Put a routing layer in front and send one function at a time to the new service. Everything else stays on the old system. Keep each slice small enough to roll back.
.NET Framework to .NET 10, older Java to a current LTS release, and app servers off Windows Server 2016 before its extended support ends in January 2027.
AWS Transform for mainframe for dependency analysis, business rule extraction, code generation and test generation. We review its output, write the equivalence tests and run parallel batches against production data.
Old applications often check passwords against their own tables and call other systems with a shared service account. We move users to SSO over OIDC or SAML and give each service its own identity.
We pieced these together from Legacy Modernization situations that come up a lot. They're patterns. You won't find a specific client in them.
case file 01
COBOL batch posting to the general ledger, two experts near retirement
composite · not a client story
Beforethe situation
A nightly COBOL batch on z/OS posts journal entries to the general ledger. The JCL has grown for decades, copybooks are shared across programs, and the two people who understand the posting rules retire within the year.
What we dothe work
Inventory JCL, programs and copybooks, and run AWS Transform for mainframe for dependency analysis and rule extraction. Review the extracted rules with both experts while they're still here, build equivalence tests from production batch inputs, and run old and new in parallel until ledger postings match.
Afterwhere you end up
The posting rules are written down and traced to code, and what the experts knew now lives in tests. Cutover waits for matching parallel runs, not for a calendar date.
case file 02
Web Forms on .NET Framework, Windows Server 2016 and one shared SQL login
composite · not a client story
Beforethe situation
It's an ASP.NET Web Forms app on .NET Framework 4.x, on Windows Server 2016 VMs. Pricing comes from a service over WCF, and everything hits SQL Server through one shared SQL login. The OS loses extended support in January 2027.
What we dothe work
Move the VMs to a supported Windows Server first, so the OS date stops driving the design. Then put a routing layer in front, rebuild the pricing calls as a .NET 10 API and move pages off Web Forms one area at a time. Give each new service its own database identity.
Afterwhere you end up
The OS deadline gets met without waiting on the rewrite. New slices ship on a supported runtime, and the database can now tell which service ran each query.
case file 03
A rating engine rewrite shelved because premiums never matched
composite · not a client story
Beforethe situation
A previous team spent two years rewriting a rating engine in Java. The new engine priced a small share of policies differently, nobody could explain why, and the project was shelved.
What we dothe work
Collect the old mismatch cases and replay them through both engines with full input capture. Trace each difference to a rule, decide with underwriting which engine is right, and add the case to the equivalence suite. Route one product line at a time to the new engine.
Afterwhere you end up
Every difference has an explanation and a decision. The new engine takes over product lines as they match, and the old one shrinks instead of running beside it forever.
How a legacy system is replaced in slices without a big-bang cutover
Put a routing layer in front. Send each request to the legacy system or the new service, one capability at a time. Run both in parallel while outputs are reconciled, and move data with change data capture until the old path can be switched off.
How a legacy system is replaced in slices without a big-bang cutoverPut a routing layer in front. Send each request to the legacy system or the new service, one capability at a time. Run both in parallel while outputs are reconciled, and move data with change data capture until the old path can be switched off.01 · USERS AND CALLERS02 · ROUTING03 · OLD AND NEW04 · DATArequestsOIDC tokennot yet movedmigrated sliceCDCold outputnew outputread and writeUsers and integrationsscreens · batch · APIsStrangler facadeAPI gateway · reverseproxyExModern identityEntra ID · OktaLegacy application.NET Framework · Java ·COBOLNew servicesmodern runtime · cloudLegacy databaseDB2 · Oracle · SQL ServerNew data storemanaged databaseOutput reconciliationparallel run diffs
New servicesmodern runtime · cloud → Output reconciliation · new output→ New data store · read and write
04 · Data
Legacy databaseDB2 · Oracle · SQL Server → New data store · CDC
New data storemanaged database
Output reconciliationparallel run diffs
Read the diagram as text
Users and integrations → Strangler facade: requests
Modern identity → Strangler facade: OIDC token
Strangler facade → Legacy application: not yet moved
Strangler facade → New services: migrated slice
Legacy database → New data store: CDC
Legacy application → Output reconciliation: old output
New services → Output reconciliation: new output
New services → New data store: read and write
how it runs
A typical engagement
We don't start a step until the last one has produced something you can check.
step 01
Assess
Code, data, integrations, runtime support dates and the people who still know the system, ranked by business risk.
step 02
Choose a path per component
Retain, rehost, refactor, rebuild or replace with a SaaS product, decided component by component.
step 03
Modernize in slices
We build each slice, test it for equivalence and run it in parallel, then switch it over behind the routing layer.
step 04
Decommission
Old components switched off, data archived to retention rules, licenses and servers released.
you keep
What you're left with
We write these for your Legacy Modernization setup, and they're working documents. Your team should be able to keep things running from them long after we've gone.
Some clients want a project team, some want a couple of engineers on theirs. Either works. Onsite, nearshore or offshore, with handovers across time zones that keep things moving.
Onsite
Engineers at your sites in the US
Nearshore
Overlapping hours with US teams
Offshore
Overnight progress on your backlog
All time zones
Coverage handed over across time zones
24-hour coverage · US Central time
OnsiteUS business hours
Nearshoreoverlapping US hours
Offshoreovernight progress
Combinedhandover, not hand-off
00:0006:0012:0018:0000:00
roles we staff
Modernization architect
Java and .NET application developer
Mainframe analyst (COBOL)
Cloud engineer
Data migration engineer
QA automation engineer
due diligence · legacy modernization
Questions to ask any partner, including us.
Put these to anyone bidding on your Legacy Modernization work. The ones who've done it answer differently from the ones who've read about it.
Q1
How will you prove the new system gives the same answers as the old one?
Every modernization comes down to equivalence in the end. Ask how they'll prove it. You want captured production inputs, compared outputs, agreed tolerances, and a named person who signs off on intended differences.
Q2
Who reviews AI-generated code, and what must it pass?
Tools such as AWS Transform for mainframe produce useful first drafts. The partner should name who reviews the output, which tests it must pass and how business experts check extracted rules.
Q3
What gets switched off after each slice, and by what date?
Programs that add new systems without retiring old ones pay for both. Each slice should end with a component decommissioned, or a date for it.
Q4
How will you capture what our retiring experts know before they leave?
Interview notes fade. Rules written into a catalog with code references, plus equivalence tests built from them, outlast the people who explained them.
Q5
What happens to the shared service account the old system uses?
Legacy systems often hit every database with a single account. If you modernize around it and never split it up, the widest credential in the estate survives the whole program.
01Should we rewrite the application or refactor it?
Full rewrites tend to run long, mostly because nobody documented how the old system behaves. Refactoring in slices is slower to get going but much safer. We only recommend a rewrite when the code can't be changed safely and the business rules are well understood.
02Can AI convert our COBOL automatically?
Tools such as AWS Transform for mainframe can analyze code, pull out business rules, and generate modern code and tests. You'll still need equivalence testing, people who know the business, and parallel runs. Treat whatever it generates as a first draft.
03How long does modernization take?
That depends on the size of the code, the integrations and how much business logic nobody wrote down. Slice-based plans ship working pieces early, so value shows up before the whole program is done.
04We still run .NET 8 or Windows Server 2016. What should we do first?
.NET 8 support ends on 10 November 2026, so plan the move to .NET 10 now. Windows Server 2016 extended support ends in January 2027. Both are usually upgrades, not rewrites, if dependencies are current.
05Can we keep the mainframe and modernize around it?
Yes, and it's often the right place to start. Wrap mainframe transactions in APIs, move reporting off the platform, and risk drops while the core keeps running. We plan what comes next once we know which parts are expensive and which are fragile.
related
Often paired with
Projects on Legacy Modernization usually end up touching one of these, so they're worth a look.