Anti-Corruption Layer

Updated Sep 18, 2026

An Anti-Corruption Layer is a boundary that translates between systems with different models, terminology, or interfaces. During legacy migration, it lets new components communicate with the old system without adopting its internal assumptions. The layer may use adapters, facades, or dedicated services to perform that translation.

An Anti-Corruption Layer separates two systems that must communicate but do not share the same model. It accepts concepts from one side, translates them, and calls the other side in its own terms. This keeps the new component from spreading legacy field names, protocols, and business assumptions through its design.

What the layer translates

Translation can cover more than data formats. The systems may divide responsibilities differently, use different identifiers, or disagree about the sequence of a workflow. The layer makes those differences explicit at one boundary.

DifferenceLegacy sideLayer responsibilityNew side
Data shapeShared or irregular recordsMap and validate fieldsDomain-specific model
ProtocolFile, queue, or old APIAdapt transport and errorsCurrent interface
VocabularyHistorical names and codesTranslate meaningsCurrent terminology
WorkflowMulti-step legacy operationCoordinate required callsOne defined capability

The layer should translate between models. If it becomes the permanent home of unrelated business rules, ownership is harder to trace and the boundary becomes another legacy component.

How it supports staged replacement

The Strangler Fig Pattern often requires the old and new systems to coexist. A moved capability may still need data or behaviour that remains in the legacy application. The Anti-Corruption Layer provides the connection without making the new component call legacy internals directly.

The direction of translation matters. A new component can protect its model when it calls the legacy system. The legacy application may need a separate adapter when it calls a new service. Treating both directions as one undifferentiated interface can hide ownership and failure behaviour.

What an audit checks

A legacy codebase audit traces the contracts that the layer must preserve and the assumptions it should contain. That includes:

  • Semantic differences. Fields or operations with similar names but different meanings.
  • State ownership. Which system is authoritative for each record during coexistence.
  • Failure mapping. How timeouts, missing data, and partial work appear on each side.
  • Security boundaries. Which identities, permissions, and validation rules apply to the call.
  • Retirement intent. Whether the layer remains after migration or disappears with the legacy system.

These checks prevent a translation boundary from being treated as a simple format converter when it also carries operational and domain meaning.

Operational consequences

The layer adds a component to the request or event path. Its logs and traces need to connect activity across both systems. Retries must account for operations that are not safe to repeat. Data mapping errors need a visible handling path rather than silent substitution.

Branch by Abstraction can introduce a related boundary inside one codebase, while an Anti-Corruption Layer commonly mediates between models or subsystems. The two can work together during migration, but they address different dependencies. One lets implementations share a contract. The other prevents one system's concepts from controlling the design of another. That distinction helps a migration plan state which boundary is temporary, which is part of the target architecture, and what evidence permits the old connection to be removed.