Skip to content
← Blog

Impact analysis: what to do before touching a legacy system

· 3 min read· architecture· legacy· method

There is a recurring moment in the life of anyone working on long-lived systems: a seemingly trivial change request arrives, and nobody can say with confidence what will happen once it is applied. The code is there, it has worked for years, and the documentation — where it exists — describes a system that no longer exists.

The instinctive response is to open the IDE and look for the class to change. That is almost always the wrong move, and not out of intellectual laziness: in a legacy system, the cost of a change is not in the change itself. It is in whatever the change touches without anyone noticing.

The code is the only trustworthy documentation

The first assumption to drop is that a source of truth exists other than the system itself. Functional specifications describe original intentions; internal wikis describe how things worked three reorganisations ago; people recount the part they personally touched.

The code, by contrast, describes what actually happens. And alongside the code, the data: a live relational schema tells the real story of an application, including the decisions nobody ever wrote down. Columns added and never populated, constraints disabled to let a migration through, tables duplicating information because at some point that was simply faster.

Reading those traces is the most informative part of the job.

Three questions before any change

The impact analysis I use comes down to three questions, asked in this order.

Who reads this data? Not who writes it — who reads it. A modified field propagates downstream through queries, reports, integrations, nightly exports, materialised views. The consumer nobody remembers is almost always the one that will break, and it is almost always a batch process that runs once a month.

What happens if this step fails halfway? Long-lived systems are full of non-idempotent operations written when volume was a tenth of today’s. A change that makes an operation slower can turn a theoretical edge case into a weekly incident.

How will I know if it goes wrong? If the answer is “a user will tell us”, the change is not ready. Not because perfect observability is required, but because a change whose outcome you cannot verify is a change you cannot actually defend.

Write the analysis, don’t just do it

Impact analysis is worth doing if it produces an artefact. Not a ceremonial document: one page listing the elements touched, the consumers identified, the known risks, and what you deliberately chose not to verify.

That last part is usually missing and is the most useful. Stating “we did not verify behaviour under concurrent load” is valuable information for whoever reads it in six months, when the problem surfaces. A known gap is a manageable risk; an implicit gap is a surprise.

The actual goal

The point of impact analysis is not to eliminate risk: on a system you did not write, zero risk does not exist. The point is to move risk out of the “we didn’t know” category and into “we knew, and we decided”.

It is a distinction that feels formal until it turns into a production incident. At that point it becomes the difference between a technical problem and a trust problem.


← All articles

Technical cookies

Always on

Essential for the site to work and to remember your cookie choice. They require no consent and cannot be disabled.

Google Analytics, to understand which content is useful. They involve a transfer of data to the United States. Disabled until you allow them.

Marketing cookies

None in use

I use none. The category is listed for transparency and would only ever be enabled with your consent.