A practical guide to understanding and transforming aging software systems
43% of global banking transactions still run on COBOL.
If you're modernizing legacy systems, you're handling revenue-critical code.
Stability, revenue, and risk keep old systems alive.
Legacy code doesn't exist because developers are lazy.
It persists because:
Two examples you might recognize.
IDENTIFICATION DIVISION.
PROGRAM-ID. CALCULATE-INTEREST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 ACCOUNT-BALANCE PIC 9(10)V99.
01 INTEREST-RATE PIC 9V999.
Still processing 43% of banking transactions globally.
SELECT customers
SCAN FOR balance > 10000
DO invoice_customer
REPLACE last_contact WITH DATE()
ENDSCAN
Powering manufacturing and distribution companies decades after official EOL.
Where modernization efforts usually fail.
Pick the path that matches risk and timeline.
Gradually replace functionality while keeping the system running.
Lift-and-shift to modern infrastructure without code changes.
Incrementally improve code quality and architecture.
Start fresh—highest risk, highest potential reward.
Incrementally improve code quality and architecture.
Start fresh—highest risk, highest potential reward.
// New modern API wraps legacy system
export class CustomerService {
async getCustomer(id: string) {
// Route to new implementation if migrated
if (await this.isMigrated(id)) {
return this.newService.get(id)
}
// Fall back to legacy system
return this.legacyService.get(id)
}
}
Key idea: Route new traffic to the modern service, keep legacy as fallback.
Before modernizing, ask:
Modernization is a business decision, not just a technical one.
The best time to start was five years ago. The second best time is now.