Event Sourcing and CQRS for Core Banking System

Event-sourcing architecture built alongside a COBOL mainframe core banking system, introducing CQRS read projections and change data capture to enable real-time...

[Overview] Scope of the engagement

This anonymized Ampity engagement involved building an event-sourcing architecture alongside a COBOL-based mainframe core banking system at a regional bank. The work introduced Kafka-based event capture from the mainframe through change data capture, purpose-built CQRS read projections and a phased approach to new digital capabilities while retaining the mainframe as the initial system of record.

This case focuses on the architecture, implementation approach and operating responsibilities. It does not provide verified before-and-after measurements or a regulatory assessment.

[Context] A reliable system with an inflexible data model

The bank had operated a mainframe-based core for decades. The system was stable, but stability had been maintained largely by limiting change. Understanding existing COBOL behavior was a prerequisite to changing the systems that depended on it. The account treats that dependency knowledge as a migration input.

The data model organized around current state with destructive updates. When an account balance changed, the previous balance was overwritten. When customer information was updated, prior values were lost. This made real-time balance visibility, historical analytics and audit reconstruction difficult.

Batch processes computed account balances overnight. Customers checking their balance saw the previous day's end-of-day figure. Third-party integrations depended on batch file exchange processed overnight. A mobile banking application had been built with workarounds for these limitations, resulting in staleness indicators visible to users.

[Diagnosis] The data model, not the hardware

The account makes a distinction between the mainframe as a compute platform and the data model it implemented. Mainframes remain suitable for certain workloads. The constraint identified in the account is the current-state model with destructive updates rather than the mainframe itself.

Event sourcing addresses this by treating each state change as an immutable event. The current state is then a projection derived from event history rather than a mutable record. Different projections can use that history, but their timeliness and completeness still require validation.

The account also notes an organizational dimension. Engineers who understood the legacy system had seen failed modernization attempts and were protective of their knowledge. The account treats their concerns as valid constraints on approach selection rather than as obstacles to remove.

[Decisions] Vendor package, mainframe modernization or parallel build

The account evaluates three approaches.

A commercial core banking package was rejected. The account records the tradeoffs the team weighed at evaluation time: implementation complexity and delivery risk for large core-banking programs, and the risk of exchanging one vendor dependency for another while losing flexibility for digital features. These reflect the considerations recorded in this account, not a general characterization of commercial core banking products.

Mainframe modernization (exposing APIs, improving without replacing) was rejected because it preserves the underlying data model problem. The bank had previously attempted modernization without success.

An event-sourced parallel build was chosen: build the event-sourced system alongside the mainframe using change data capture to create an event stream from mainframe operations, and gradually migrate capabilities. The mainframe continues as the system of record until specific workloads are validated on the new architecture. CQRS read projections are purpose-built for each consumer pattern rather than shared.

Using the mainframe itself as the long-term event source via CDC was described as a bridge approach for the initial phase but not a final state, because it preserves mainframe cost and constraints indefinitely.

[Design] Event capture and projection layer

The source narrative names Debezium and Kafka for change capture and distribution. The exact source database, connector version and supported object inventory are not established here; do not infer compatibility with every mainframe platform from these names. CDC captures database-level record changes; these do not necessarily correspond to complete business events, and a multi-record mainframe transaction may surface as a sequence of individual change records that require event assembly before they represent a coherent business operation. Kafka partitions events by account number for ordering within each partition, but per-partition ordering is not the same as end-to-end correctness of business transactions that span multiple records or systems.

CQRS read projections are built from the event stream: an Account Balance Projection for fast lookup, a Transaction History Projection for searchable history and an Analytics Projection for business intelligence. Each is optimized for its query pattern independently.

For new capabilities, the account describes writing events to Kafka and synchronizing changes with the mainframe. This dual-write arrangement is described as explicitly temporary, with a planned path to removing it as mainframe workloads migrate.

Dual writes introduce failure paths. A write that succeeds in the event store and fails to synchronize to the mainframe (or vice versa) creates a consistency gap requiring reconciliation. The account notes this complexity as intentional and temporary, not as a solved problem.

For reuse, establish currency units, decimal precision and rounding at each posting boundary. Verify that conversions and projection calculations preserve the required amounts; an event store does not establish accounting correctness.

[Approach] Phased rollout in six stages

The account describes six phases. Phase one deployed the Kafka cluster and Debezium connectors without changing any existing system other than adding database monitoring. Phase two built the Account Balance and Transaction History projections and ran automated reconciliation to confirm that projected balances matched mainframe balances. Phase three updated the mobile banking application to read from projections, providing real-time balance visibility. Phase four built the Analytics Projection and automated regulatory reporting from event data. Phase five used the event foundation to build new digital features not possible on the legacy architecture. Phase six moved selected low-risk transaction types to process primarily through the new architecture with mainframe synchronization retained for system-of-record compliance.

Full mainframe retirement was described as a longer-horizon goal beyond the initial phased build. The account does not claim mainframe retirement was completed.

Reconciliation in phase two was automated: any discrepancy between projected and mainframe balances triggered investigation. This is described as an ongoing gate for confidence, not a one-time check.

[Delivery scope] What the implementation covered

The described scope covers change capture, account and transaction projections, reconciliation and staged consumer migration. Freshness, availability, cost savings, customer engagement and regulator acceptance are not established results of this account.

Before treating an event history as an audit source, establish its completeness, retention, access controls and reconciliation to the authoritative ledger.

[Operating considerations] Questions for similar implementations

Change data capture from a mainframe requires that the source database's transaction log is accessible and that the connector supports the relevant database version and object types. Test the CDC configuration against the full set of transaction types in the workload, not only the common paths.

Projection reconciliation is an ongoing responsibility, not only a delivery-time check. Define how discrepancies are detected, investigated and resolved after initial deployment. A projection that drifts from the source of record without detection creates silent inconsistency.

Event schema evolution needs governance. When the meaning of a field changes or a new event type is introduced, existing projections may need to handle both old and new event shapes. Define the versioning strategy before the first breaking change is needed.

Kafka retention policy determines how far back event replay can go. Set retention based on the longest replay window any projection requires. Adding a new projection after events have expired from the log requires a different initialization strategy.

The mainframe remains the system of record during the transition. Changes to mainframe behavior (schema, stored procedures, batch processing) can affect the event stream and projections downstream. Establish a change notification process between mainframe and event-store owners.

[Applicability] When event sourcing with CQRS applies

Event sourcing with CQRS is relevant when current-state systems create audit, analytics or real-time capability gaps, when the organization needs a complete history of state changes for regulatory or business reasons, and when different consumers of the data have sufficiently different query patterns to justify purpose-built projections.

Change data capture from a legacy system is a useful bridge when the legacy system cannot be immediately replaced. CDC does not expose all internal mainframe operations. Test coverage of the required event types before building the migration dependency on it.

Event sourcing introduces complexity in schema evolution, projection management and eventual consistency between projections and the source of record. A system where current state is sufficient and historical queries are infrequent does not benefit from that complexity.

Parallel operation of legacy and event-sourced systems adds cost and operational responsibility during the transition period. Organizational commitment to sustaining that parallel period is a precondition for the approach to succeed.

Technical reference

Debezium Db2 connector documentation describes row-level change capture and version-specific setup. It is a reference for connector assessment, not confirmation of this project's source database, connector version or captured object coverage.