Skip to content

Assessment before commitmentIncremental, tested migration

Resources

How to assess a legacy codebase before you migrate it

4 min read

How to assess a legacy codebase before you migrate it

A practical outline of a legacy assessment: inventory, live versus dead code, data, interviews with operators, and a decision per component, shown on a COBOL batch billing run.

The cheapest mistake in a migration is made before it starts: choosing a target and a schedule without knowing what the system actually does. An assessment fixes that. This article describes how engineers examine a legacy codebase, using a COBOL and DB2 batch billing run as the running example.

Build an inventory before you build a plan

Start by listing every artifact that makes up the system. In a mainframe batch estate that means programs, copybooks, JCL and procedures, scheduler definitions, DB2 tables, VSAM files, CICS transactions, message queues and the files that leave the building for other systems.

For the billing run, the inventory might show a chain of job steps: extract usage, rate it, apply credits, format statements and send files to a print vendor and a general ledger. Writing this down as a dependency map is the first real deliverable, because most estates have no current diagram of it. Static analysis tools help for common languages. Where tools do not cover a language or a dialect, someone has to read the code, and a good report says which findings came from which.

Be wary of size alone. Lines of code are a poor predictor of effort. A small program full of date arithmetic and special cases can cost more to migrate than a large one that does one simple thing many times. Complexity, coupling to other programs and the quality of existing tests say more about the work ahead.

Find what is live and what is dead

Code that exists is not code that runs. Scheduler history and transaction logs, taken over a full business cycle, show what actually executed. Include the periodic runs: a program that fires once a year at fiscal close is easy to miss in a one-month sample and expensive to forget.

Dead code matters in two directions. Removing it shrinks the migration. But some code that looks dead is only rare, so mark candidates and confirm with the people who operate the system before anything is dropped.

In the billing run, a credit adjustment program might show no executions in a normal month. A look at the scheduler shows it runs once a year, after an annual rate change. Dropping it would have broken the next rate cycle, and nobody would have noticed until then.

Read the data as well as the code

Business rules live in data too. Rate tables, code tables and configuration records often decide behavior as much as program logic does. Study the schemas and the copybook layouts: packed decimal fields, redefined areas, character set conversions and date formats all cause defects in a naive migration.

Data quality shows up here as well. Duplicate keys, placeholder values and fields reused for a second purpose are common after decades of change. They do not block a migration, but they should be known before a data load is planned, not discovered during one.

Talk to the people who run it

Operators and support staff know things that never reached documentation: the job that needs a manual restart, the spreadsheet that corrects a monthly report, the customer whose account follows a special rule. A short interview with questions such as "what do you do when this job fails" often finds work the system does outside the system.

Ask also what has been changed recently and why. Recent change shows where the business is still moving, which affects which components are safe to migrate first.

Turn findings into a decision per component

The output of an assessment is not one verdict on the whole system. It is a decision for each component: retain, wrap with an API, rehost, replatform, refactor, rebuild, replace or retire. Rank them by business value, technical condition, coupling and risk, and choose a first slice that is small, real and loosely connected.

In the billing example, statement formatting might be a good pilot because it sits at the edge, has a clear output to compare and touches no rating logic. The rating engine, with its rules built up over years, is a later and more careful step, and might be best left alone until tests describe it well.

Write each decision down with the evidence behind it and the open questions that remain. A roadmap that says why a component is retained is as useful as one that says how another is moved, because it stops the same debate from restarting every quarter.

Our legacy code audit follows this shape. For language-specific detail, see COBOL modernization and legacy application modernization.

A note on limits: tools, cloud services and practices change, and results depend on the system. Treat this as general guidance, and expect a real assessment to turn up things this outline does not mention.

Chat on WhatsApp