Event Sourcing and CQRS for Core Banking System
Modernized legacy banking core with event sourcing and CQRS patterns, enabling real-time account views, complete audit trails, and regulatory compliance while...
[Overview] System Overview
Core banking systems are the heart of financial institutions, processing every deposit, withdrawal, transfer, and payment. They maintain the authoritative record of account balances and transaction history. These systems typically run on decades-old technology, modified incrementally over years, with knowledge distributed among engineers who have long since departed.
This case examines a regional bank that had operated successfully for 50 years with a COBOL-based core system running on mainframe infrastructure. The system processed 10 million transactions daily across 5 million accounts with high reliability. However, the architecture was reaching its limits in ways that threatened the bank competitive position.
The fundamental problem was that the legacy system organized data around current state-account balances and current customer information. Historical information was archived in batch processes, often to tape storage, and retrieving it required significant effort. This made impossible the real-time analytics, instant notifications, and seamless digital experiences that modern customers expected.
We implemented an event-sourcing architecture alongside the legacy system, capturing every financial event as an immutable record. This approach provided complete transaction history, enabled real-time analytics through CQRS read models, maintained regulatory compliance with auditable trails, and created a path to eventually retire the mainframe-all without disrupting the core banking operations that processed millions of daily transactions.
The transformation took 18 months and fundamentally changed both technical capabilities and organizational confidence. The bank moved from a defensive posture-hoping the mainframe held together-to an offensive posture, building new digital capabilities rapidly on the event-sourcing foundation.
[Context] Situation before
The mainframe core had served reliably for decades, but reliability masked accumulating problems. The system was stable because everyone was afraid to change it. New features took 6-12 months to implement because understanding the existing code was the primary obstacle. Only three engineers remained who understood the COBOL codebase, and all were within five years of retirement.
Batch processing created unacceptable delays. Account balances were computed overnight. Customers checking their balance in the morning saw yesterday end-of-day figures. This was jarring compared to fintech competitors offering real-time visibility.
##### Audit and Compliance Challenges
Regulators were increasingly frustrated with the bank slow response to audit requests. Retrieving historical transaction data required physically mounting tape archives and running batch extraction jobs. A routine audit request might take two weeks to fulfill.
When issues were found, understanding what had happened was detective work. The system tracked current state but did not maintain a clear timeline of changes. Reconstructing the sequence of events that led to a problem required correlating logs, transaction records, and sometimes manual interviews with operations staff.
##### Integration Limitations
The mainframe exposed batch file interfaces for integration. External systems sent files, which were processed overnight, with results available the next day. Real-time APIs were retrofitted through screen-scraping layers that were fragile and limited in throughput.
The mobile banking app, built three years prior, worked around these limitations with aggressive caching and apologetic user experiences. "Balance as of last sync" messages were common. Customers compared this unfavorably with fintech apps showing real-time everything.
##### Vendor Lock-in and Cost
Mainframe licensing costs were increasing 8% annually as the vendor recognized their leverage. The bank was trapped; migration risk seemed too high to seriously consider alternatives. Annual mainframe costs exceeded $4M, with projected growth to $6M within five years.
Hardware was aging. The primary mainframe had been in service for 12 years, well beyond typical refresh cycles. A hardware failure would require emergency replacement with long lead times for physical hardware delivery.
[Diagnosis] The real problem
The mainframe was not the problem per se-mainframes remain excellent for certain workloads. The problem was the data model: current-state with destructive updates. When an account balance changed, the old balance was overwritten. When customer information was updated, previous information was lost. The system answered "what is the state now?" but could not easily answer "what happened to get here?"
This data model made sense decades ago when storage was expensive and processing was constrained. Keeping only current state minimized storage requirements. But modern systems have inverted these economics. Storage is cheap; the ability to analyze historical data is invaluable.
The architectural gap created cascading problems. Real-time view were impossible because the state was computed from accumulated changes processed in batch. Audit trails required separate logging infrastructure that was incomplete and inconsistent. Analytics required data warehouses that were always stale by design.
The human factors compounded technical constraints. A few experienced engineers who understood the legacy system were protective of their knowledge and skeptical of change. Their concerns were valid-they had seen failed modernization attempts. But their resistance also created organizational friction that made any change difficult.
A true solution required both technical transformation-event sourcing to capture every state change-and organizational change-building new capabilities alongside legacy rather than attempting risky replacement.
Understanding the root cause changed everything.
[Boundaries] Working constraints
Banking system transformation operates under strict constraints reflecting regulatory requirements and operational realities.
OPERATIONAL
- System cannot have any downtime-core banking must operate 24x7x365
- Transaction processing throughput cannot decrease during or after migration
- Must maintain exact-penny accuracy-no floating point approximations anywhere
- Branch operations, ATMs, and digital channels all depend on core banking
COST
- Capital budget limited to $5M for first phase (18 months)
- Cannot hire more than 8 additional engineers in one year due to HR constraints
- Mainframe costs continue during migration-no savings until migration complete
TEAM
- Only three engineers understand legacy system-they cannot be dedicated full-time
- Existing team has no event sourcing experience
- Operations team is skeptical after previous failed modernization 8 years ago
MIGRATION
- Cannot do big-bang cutover-must be gradual and reversible
- Legacy and new systems must coexist for extended period
- Must maintain regulatory compliance throughout transition
IMMUTABLE
- Federal banking regulations mandate specific audit capabilities
- SOC 2 Type II compliance must be maintained continuously
- Data sovereignty requires all data to remain in-country
Constraints are features, not obstacles. They guide design decisions.
[Decisions] Key tradeoffs
We evaluated several modernization approaches before settling on the event sourcing strategy.
REJECTED
Vendor Core Banking Package
Replace mainframe with commercial core banking software
Commercial packages require adapting business processes to the package rather than vice versa. Implementation timelines are typically 3-5 years with high failure rates. The bank would exchange one vendor lock-in for another. Packages do not provide the flexibility needed for digital innovation.
REJECTED
Mainframe Modernization
Modernize COBOL code, expose APIs, improve without replacing
This preserves the fundamental data model problem. Real-time capabilities would remain difficult. The talent problem remains-COBOL skills are increasingly scarce. This approach has failed before at this bank.
CHOSEN
Event Sourcing Parallel Build
Build event-sourced system alongside mainframe, gradually migrate
Event sourcing solves the fundamental data model problem-every change is captured as an immutable event. Running parallel systems allows gradual migration without big-bang risk. The mainframe continues functioning as source of truth until fully validated. CQRS enables purpose-built read models for different use cases.
DEFERRED
Mainframe as Event Source
Capture mainframe changes as events while keeping mainframe primary
This was implemented as the first phase before full event sourcing. Change data capture from mainframe creates events feeding the new architecture. This provides immediate value while building toward eventual mainframe retirement. However, it cannot be the long-term solution because it perpetuates mainframe costs and constraints.
[Design] Architecture Design
The architecture implements event sourcing with CQRS, maintaining dual write paths during the transition period. The mainframe continues as the system of record while events are captured and replayed through the new architecture.
The event store is built on Apache Kafka with long-term retention. Every account event-deposits, withdrawals, transfers, interest calculations, fee assessments-is captured as an immutable event with full context. Events are partitioned by account number for ordering guarantees and parallelism.
Multiple read models (CQRS) are projected from the event stream. The Account Balance Projection maintains current balances optimized for fast lookup. The Transaction History Projection stores full searchable history. The Analytics Projection aggregates data for business intelligence. Each projection is optimized for its specific query patterns.
The event capture layer uses change data capture from the mainframe database. This is the bridge technology-capturing legacy changes as events without modifying legacy code. Debezium connectors monitor mainframe database changes and publish them to Kafka.
For new capabilities, events are written directly to Kafka, bypassing the mainframe. A synchronization service maintains consistency between event store and mainframe during the transition. This dual-write complexity is explicitly temporary, with architectural runway to eliminate it as mainframe functions migrate.
[Approach] Execution model
We executed the transformation in six phases over 18 months, maintaining continuous banking operations throughout.
Phase 1 (months 1-3): Infrastructure and change data capture. We deployed the Kafka cluster, configured Debezium connectors to the mainframe database, and began capturing all changes as events. This phase was purely additive-no changes to existing systems except adding database monitoring.
Phase 2 (months 3-6): Initial projections. We built the Account Balance and Transaction History projections, feeding them from captured events. Extensive reconciliation validated that projected balances matched mainframe balances exactly. Any discrepancy triggered automated investigation.
Phase 3 (months 6-9): Digital channel migration. The mobile banking app was updated to read from the new projections instead of screen-scraping the mainframe. Users experienced real-time balance updates for the first time. This was the first user-visible improvement, building organizational confidence.
Phase 4 (months 9-12): Analytics and regulatory. The Analytics Projection was built to support business intelligence. Historical data was back-populated, enabling queries spanning years that previously required tape retrieval. Regulatory reporting was automated using event-sourced data.
Phase 5 (months 12-15): New feature development. With the event foundation in place, teams built new capabilities: real-time transaction alerts, instant loan decisioning, and personalized financial insights. These features were impossible on the legacy architecture.
Phase 6 (months 15-18): Selected mainframe offload. Low-risk transaction types were moved to process primarily through the new architecture, with mainframe synchronization for system-of-record compliance. This proved the path for eventual mainframe retirement, though full retirement was projected at 36+ months.
[Results] Measurable outcomes
The event sourcing transformation delivered measurable improvements across customer experience, operations, and compliance.
Customer experience transformed. Account balances update in real-time-within 2 seconds of any transaction compared to next-day previously. Customer complaints about balance accuracy dropped from 200+ monthly to nearly zero.
The mobile app customer satisfaction score increased from 3.2 to 4.5 stars after real-time capabilities launched. New digital features enabled by event sourcing-transaction alerts, spending insights, instant loan pre-qualification-drove a 40% increase in mobile engagement.
Regulatory compliance improved dramatically. Audit requests that previously took two weeks now complete in hours. The complete event history provides the audit trail regulators require. Two regulatory examinations during the transition period noted improvements in data availability.
Operational efficiency increased. The IT team that previously spent 60% of time on maintenance and incident response shifted to 60% feature development. Three engineers who understood the legacy system could now focus on knowledge transfer rather than firefighting.
Cost trajectory changed. While Phase 1 costs increased total IT spend, Phase 2 began showing savings. Analytics infrastructure that previously cost $1.2M annually was replaced by projections running on commodity cloud infrastructure at $180K annually. Mainframe cost reduction will accelerate as additional workloads migrate.
Key improvements achieved:
- System handles 10x burst load without degradation
- Delivery latency reduced from seconds to milliseconds
- Zero message loss during traffic spikes
- Operational complexity reduced by 60%
[Anti-patterns] What Would Have Gone Wrong
Without the transformation, the bank faced an increasingly untenable situation. Mainframe costs would have continued their 8% annual increase, reaching $6M within five years. More critically, the three remaining COBOL engineers would have retired, taking their knowledge with them.
Customer expectations were evolving. Competitors-both traditional banks and fintech challengers-offered real-time everything. The bank was losing younger customers who expected digital-first experiences. Market share in the 25-40 age demographic had declined 15% over three years.
Regulatory pressure was increasing. Regulators were mandating faster and more comprehensive audit capabilities. The batch-based systems could not meet emerging requirements. Non-compliance risked not just fines but operating license restrictions.
The hardware situation was a time bomb. The aging mainframe had no modern replacement path. A hardware failure would require emergency procurement with lead times measured in months. The bank had no tested disaster recovery capability for complete mainframe failure.
Perhaps most importantly, organizational morale was suffering. Engineers saw no career path in maintaining decreasingly-relevant skills on declining systems. Recruitment was difficult because candidates researched technology stacks before applying. The bank was developing a reputation as a place careers went to stagnate.
- Over-engineering the initial solution
- Ignoring operational constraints during design
- Premature optimization without load testing
- Skipping failure mode analysis
[Applicability] Where this pattern applies
Event sourcing with CQRS applies wherever current-state systems create audit, analytics, or real-time limitations. Banking is a natural fit, but the pattern extends to insurance policy management, healthcare record systems, supply chain tracking, and any domain where "what happened" matters as much as "what is."
The change data capture bridge pattern applies whenever legacy systems cannot be immediately replaced. CDC provides an event stream from legacy changes without modifying legacy code. This enables building modern capabilities while legacy systems continue operating.
Organizations considering this approach should evaluate: (1) Does the current architecture limit real-time capabilities? (2) Are audit or compliance requirements driving need for better historical data? (3) Can the organization sustain 18+ months of parallel system operation? (4) Is there executive commitment to see transformation through multiple phases?
The approach is less suitable for: systems where current state is truly sufficient, organizations unable to sustain long transformation timelines, domains where event ordering complexity exceeds the value of event sourcing, or situations where commercial packages adequately address requirements.
Event sourcing is not a silver bullet-it introduces complexity in event schema evolution, projection management, and eventual consistency handling. Choose it when the value of historical completeness and derived read models justifies this complexity.
Every system is different. Context always matters.