In IT, the answer to “How should this be done?” is almost always “It depends.” Legacy modernization is no exception. Typically, this leads to a follow-up regarding the desired outcome: should the system be retired, retained, rehosted, relocated, repurchased, replatformed, or refactored? These options are collectively referred to as the 7 Rs of legacy modernization. The chosen outcome directly informs and determines the appropriate modernization strategy and approach.
Often, the objective is just to move the application from on-premises to a cloud vendor with no code changes. This approach is informally called “lift-and-shift”, a variation of rehost. Other times, multiple of these objectives are combined as part of the modernization effort. This involves redesigning the application to take advantage of modern features (e.g., breaking a monolith into microservices), while also moving from on-prem servers to the cloud. In these multi-objective journeys, the next critical question is whether to do a big-bang replacement or gradually replace (a.k.a strangler fig pattern) smaller parts of the legacy system with new services on the cloud. Several enterprises go through this journey, typically once in a few years, and at least once in a decade.
The COTS Black Box
Many enterprises are tethered to legacy applications running for over 20 years with minimal modification (typically only security patches), or heavy commercial-off-the-shelf (COTS) applications, where you rarely have the source code, but the database and schemas remain accessible.
To modernize, architects often want to replace these “black boxes” with microservices incrementally, starting with low-priority flows or specific business capabilities. This is where a Change Data Capture (CDC) and Anti-Corruption Layer (ACL) bridge becomes invaluable.
The following illustrates a legacy modernization strategy that uses a CDC and ACL bridge to transition from a monolith (COTS application) to a microservices architecture. Real-time data changes from the legacy database are streamed via Debezium and Apache Kafka to an ACL service, which translates the old data models into a format compatible with the modern environment. This architectural pattern ensures eventual consistency and continuous synchronization between the systems, allowing for a phased migration while maintaining service to client applications.

The Anti-Corruption Layer Pattern
The Anti-Corruption Layer acts as a protective boundary between your modern microservices and legacy systems (black box). Think of it as a translator that speaks both languages fluently; it understands the legacy system’s quirks and data structures but presents a clean, domain-driven interface to your new services.
The ACL services are architecturally transient applications written to support this transitionary period. In the flow shown above, ACL consists of applications that consume Kafka events. It translates the legacy “messy” data model into clean, modern domain models before passing them to the new ecosystem.
Combining ACL and CDC
CDC monitors database transaction logs to detect and capture data changes in real-time. Instead of polling databases or modifying application code, CDC taps directly into the database’s native recovery logs. Modern databases maintain transaction logs for recovery purposes. CDC tools like Debezium read these logs and publish change events to a message broker (like Kafka):
This architecture supports a gradual strangler fig migration. Initially, all writes go to the legacy system, CDC captures them, and ACL translates them. Over time, you migrate write operations to microservices while maintaining backward compatibility.
Early Steps to EDA
Adopting CDC and ACL represents your first concrete steps toward a fully event-driven architecture (EDA). This foundation enables several powerful capabilities that transform how your systems communicate and scale. Your initial implementation creates an event backbone, a stream of domain events (in the form of database CDC updates) that represent everything happening in the legacy application.
Any enterprise migrating towards EDA needs to adopt an incremental approach to ensure the changes are absorbed non-disruptively and gradually. As moving towards EDA requires more than technical challenges, a change in mindset towards asynchronous events, this CDC-based approach is one of the effective strategies. As the evolutionary next step, the microservices can move towards event sourcing and architectural patterns like Saga and Command Query Responsibility Segregation (CQRS).
Outbox Pattern
As the enterprises move towards EDA, the transactional outbox pattern is required to ensure data consistency and reliability. The outbox pattern prescribes a “dual-write” operation, where a single operation involves both a database write operation and an event notification. Technically, the application code manually writes to an “Outbox” table in addition to writing to the primary transaction table. These dual writes are wrapped within a single transaction to ensure atomicity and consistency. A watcher/poller application reads the entries from the outbox table, posts to a messaging platform like Kafka, and marks the row as processed.
In the legacy modernization context, you usually cannot use the classic Outbox Pattern. This is because the legacy application is either a monolith written a decade ago or a COTS product that does not allow such extensions. This is where the CDC implementation prescribed above captures the spirit of the Outbox pattern by using the database’s internal log as the outbox. Debezium acts as the high-performance, automated “Relay.” Instead of you writing a custom watcher/poller to query a table every 5 seconds, Debezium “tails” the database log in real-time.
Conclusion
Modernizing legacy systems doesn’t require a risky big-bang rewrite. By combining Change Data Capture and the Anti-Corruption Layer, you create a migration path that’s both safe and pragmatic. CDC captures every change from your legacy database in real-time, while the ACL translates these changes into clean domain events that your modern microservices can consume.
This foundation unlocks the door to event-driven architecture. Your services become loosely coupled, independently deployable, and resilient. The Outbox Pattern ensures that as you build new capabilities, you maintain data consistency across distributed systems. What starts as a simple translation layer evolves into a robust event backbone that powers your entire business.
The strangler fig approach works because it’s gradual and reversible. You build confidence with each small migration, learning what works in your specific context. Your legacy system continues serving customers while new services quietly consume its data stream. Over time, more business logic migrates to microservices, but the legacy system never experiences a high-risk cutover.
Launch and Iterate: Implement CDC for a single table, build an ACL to translate its events, and let one new microservice consume the clean domain events. Learn from this experience, then expand. This measured approach has helped countless enterprises successfully modernize systems that seemed impossibly entangled. Your modernization journey begins not with architecture diagrams and planning documents, but with a single Debezium connector and a microservice that translates events. The future is built one event at a time.










