BLOG Legacy Is About Context
David Schmid

A few years ago, I was asked to look at a system that everyone agreed needed to be replaced.

The software was more than 20 years old.

Documentation was incomplete.

Parts of the technology stack were decades old.

The verdict seemed obvious:

"This is legacy software."

It had to be replaced.

After a few days, however, it became clear that the software itself wasn't the biggest problem.

Nobody could explain everything connected to it.

Aerial view of a complex railway network with branching and interconnected tracks

Table of Contents

The Myth of Legacy Software

The word legacy has become almost synonymous with bad.

Old code. Old databases. Old operating systems. Old programming languages.

But age alone tells us very little about the quality of a system.

Some 50 year old COBOL systems still process critical transactions every day with remarkable reliability. At the same time, plenty of "modern" systems become difficult to maintain after only a few years.

When we describe software as legacy, we often mix up three different questions:

A system can be old and easy to operate. It can be difficult to change while still providing enormous business value. It can also be technically modern and no longer fit the needs of the organization.

Only the third question directly justifies replacement.

The second suggests, that we should improve the ability to change the system safely.

The first question, its age, tells us almost nothing on its own.

Referring to Micheal Feather's work on legacy code, the practical problem is not that code is old, but that changing it is risky because of a lack of reliable feedback and an incomplete understanding of its behaviour.

From an architectural perspective, Gregor Hohpe makes a similar point: architecture should be judged against the expected rate of change, meaning that a stable system in a stable business domain may not need the same flexibilty as a product that changes every week.

Old Does Not Mean Unmaintained

Another distinction worth making is between old and unmaintained software.

A programming language, database or system dependency may be old while still being actively maintained, supported and widely used. At the same time, a relatively new library may already be abandoned and no longer receive bug fixes or security updates.

The real concern is therefore not only when a technology was created, but whether it is still maintained and whether the organization can operate it responsibly.

A system can also become outdated if teams stop improving it, documentation is neglected and necessary upgrades are postponed. The system continues to operate while its condition gradually deteriorates.

There can be different reasons for this, but often it comes down to whether an organization is willing to invest in the old system. This is especially common when a replacement has already been announced.

In that sense, calling a system legacy can become a self-fulfilling prophecy: we stop investing in it because we plan to replace it, then point to the resulting problems as evidence that it must be replaced.

Software Accumulates Context

What at first glance might look like a single application may be only the tip of the iceberg, with a much larger network of technical and organizational relationships hidden beneath the surface.

Martin Fowler's work on enterprise application architecture shows this complexity from a technical perspective. Enterprise software often combines business logic, data access, integration and transaction management.

Following Donella Meadows' system thinking, a system is not defined only by its individual components, but also by the relationships between them, the feedback loops they create and the purpose they serve.

The longer a system operates, the more context accumulates around it:

Someone knows how to restart it.

Someone checks a report every morning.

Someone understands which errors can be ignored and which require immediate attntion.

Someone has built a process around behaviour that may never have been formally documented.

And so on.

Eventually, the software itself becomes only one part of a much larger system.

And every one of those relationships becomes a potential source of risk during change.

The boundry around an application is often drawn for convenience. In reality, it may also include people, procedures, incentives and external organizations.

This is why replacing one technical component does not necessarily change the behaviour of the larger system. The surrounding relationships and dependencies remain.

Hidden Dependencies

A migration may appear to be a simple replacement: Replace system A with system B.

The difficulty begins when the team discovers an undocumented batch process, a file export still used by a partner, direct access to a shared database, an API that an other department still depends on or a yearly report supporting an important decision.

Suddenly, the project is no longer about replacing software. It becomes an exercise in discovering relationships.

Some dependencies are documented and some visible in code. Others may be hidden in scheduled jobs, database access, message flows or operational routines.

An overlooked integration can lead to chain reactions and cascading failures far beyond the system being changed.

The real challenge in a migration is therefore often not building the replacement.

It is discovering everything that the existing system is already connected to.

Looking for dependencies is not just about reading source code. Many integrations exist outside the application itself. Some exchange files, others communicate through databases, APIs or message brokers. Understanding these patterns provides a useful framework for discovering relationships that might otherwise be overlooked.

Hohpe and Woolf describe four common integration styles: file transfer, shared databases, remote procedure invocation and messaging. Each creates different forms of coupling, but they all have one thing in common: they establish relationships that may survive long after the original implementation has been forgotten.

Looking at a legacy system through these integration patterns provides a practical checklist for discovering dependencies that are often invisible in the source code alone.

Technical Debt and Knowledge Debt

Technical debt and knowledge debt are closely related, but they are not identical.

Knowledge debt is the gap between how a system actually works and what the organization can confidently explain about it.

Technical debt is often inspectable. Teams can identify duplicated logic, tight coupling, missing tests, outdated dependencies or fragile code. These issues make software more difficult and expensive to change.

Knowledge debt is harder to locate because it is distributed across systems, documentation, processes and people.

It lives in assumptions.

In operating habits.

In historical decisions whose original reasoning has been forgotten.

In undocumented dependencies.

In exceptions that only one person knows how to handle.

An undocumented feature may contribute to both kinds of debts. The implementation itself may be technically difficult to maintain, while the organization's inability to explain why it exists or who depends on it represents knowledge debt.

There is also a difference between a know-how gap and knowledge debt.

A know-how gap means that the required expertise is currently missing. For older programming languages such as COBOL, for example, it may be difficult to find developers with the necessary technical skills. The knowledge still exists, but it is not readily available to the organization.

Knowledge debt is different. It is the accumulated risk created when important knowledge is repeatedly left undocumented, unshared or dependent on individual memory.

For example, only one employee may know why a particular batch job must run before the monthly closing process. Another person may be the only one who understands how to recover the system after a specific failure. If that knowledge is never documented or transferred, the organization gradually becomes dependent on a small number of individuals.

A know-how gap can often be addressed by hiring, training or external support.

Knowledge debt first requires discovering what the organization no longer knows.

Michael Feathers describes many of the practical symptoms of this problem: changes take too long, developers do not understand the code well enough to modify it and nobody can confidently predict what might break.

Gregor Hohpe extends this beyond the source code: Important knowledge may be embedded in organizational structures, operational routines and assumptions that nobody has questioned for years.

This uncertainty can be more dangerous than poor code.

Poor code can often be inspected.

Unknown consequences cannot.

Legacy Is Accumulated Context

Perhaps we should stop thinking about legacy software simply as old software.

A more useful definition might be:

Legacy software is software whose technical structure has become entangled with the history of the organization.

Over time, a system accumulates context that may be distributed across documentation, infrastructure, processes and people.

Replacing the software does not automatically replace that context. Ignoring it only makes the migration more dangerous.

This does not mean that old systems should be preserved indefinitely.

It means understanding and extracting the surrounding knowledge before the software is removed.

Case Study: ASAL 2.0

A recent example from Switzerland illustrates why the age of a system should not be the only factor in a replacement decision.

Until the end of 2025, Switzerland’s unemployment insurance funds used a payment system whose origins went back to the 1980s. At the beginning of 2026, it was replaced by the new centralised ASAL 2.0 platform.

After its introduction, the new system experienced significant technical and performance problems. Payments were delayed, affecting people who depended on unemployment benefits.

According to recent reporting, assessments conducted before the launch had already raised concerns about the platform's security, complexity, performance and maintainability. SECO maintains that the relevant security issues were addressed before the launch and that the later operational problems did not emerge in a form that could have been fully anticipated.

The point is not that old software should never be replaced.

The case illustrates that replacing an older system with a newer one does not automatically reduce operational risk.

The relevant question is not whether the replacement is newer.

It is whether the organization understands it well enough to rely on it.

Start With Discovery

Modernization should begin with discovery.

Before changing a system, understand its trust boundaries, dependencies and operational context.

Ask:

Only after understanding the system and its relationships does it make sense to discuss modernization.

Sometimes replacement is the right decision.

Sometimes it is not.

Conclusion

In archaeology, removing an old layer before examining it can destroy information forever.

Legacy systems are similar. They contain traces of earlier decisions, constraints, integrations and operating practices.

The goal is not to preserve every layer forever.

It is to extract the knowledge contained in that layer before removing it.

Before retiring an old system, an organization should be able to explain:

Because the most dangerous part of a legacy system is rarely its age.

It is the knowledge the organization has already lost about it.

Need an Independent View?

Many modernization projects begin before anyone fully understands the existing system. That uncertainty often becomes the largest source of technical and organizational risk.

At join.tech, I help organizations understand complex software systems before changing them. Typical questions include:

A typical discovery engagement delivers:

The result is a practical assessment that helps reduce uncertainty before larger investments are made.

Learn more at join.tech.

About the Author

I'm David Schmid, founder of join.tech.

My work focuses on helping organizations understand, modernize and secure complex software systems through architecture, technical discovery and systems integration.

If you're facing a challenging migration, integration project or architectural decision, feel free to get in touch.

References

Comments

No comment on this post yet... Initiate the dialogue - be the first to illuminate this page with your thoughts!

Leave a Comment

Please preserve the rules of respect and avoid any shadow that might fall upon the realm. Keep your discourse pure and use simple characters. Your scroll shall contain no more than a thousand characters.

Only the worthy may share their wisdom beneath the sacred tree of insight. To prove yourself a true hero and not a shadowy automation, solve this puzzle:

captcha