Back to Research
Event-sourced banking timeline showing account state reconstruction from events
Engineering March 18, 2026 ยท Tim Normark

Event-Sourced Banking: Architecture Built for Audit, Safety, and Scale

Most banking platforms today are built around a familiar model. Databases store what accounts, loans, and balances look like at this moment, and applications update those records as things change. This is often referred to as an update-in-place persistence model. Historical information exists, but it typically sits beside the system rather than defining it.

Over time, this model runs into fundamental limitations. Banks need full auditability, precise historical reconstruction, safe retries, and the ability to evolve products without risking existing data.

The usual response is to layer additional systems on top: audit logs, reconciliation jobs, retry guards, historical tables, migration frameworks. Each new capability becomes another system that must stay in sync.

With Lana, our banking and lending platform, we took a different approach. Instead of layering these guarantees on later, we designed the architecture so they are natural consequences of how the system works.

Traditional Approach

  • Mutable database rows overwritten on each change
  • Separate audit log that can drift from reality
  • Database migrations to evolve products
  • Custom retry guards to prevent duplicates
  • Historical reconstruction requires extra systems

Event-Sourced (Lana)

  • Immutable events are the source of truth
  • Audit trail is the operational data
  • New event types extend products additively
  • Idempotency is built into the model
  • Replay events to reconstruct any point in time
Architecture

Every Entity Is Event Sourced

In our banking platform, Lana, every domain entity is reconstructed from a sequence of immutable events.

The platform spans domains such as credit, deposits, customers, accounting, custody, access control, governance, and collections, all built on the same event-sourced foundation.

A credit facility, for example, is not stored as a mutable record. Its lifecycle is represented as events such as facility initialized, activated, collateral added, interest accrued, disbursement issued, and matured.

Instead of storing only the latest state, the system stores how it came to exist. That single difference unlocks capabilities that are difficult to implement reliably in traditional architectures, while still supporting efficient querying and access patterns.

Comparison of a state-based model versus an event-sourced model showing how Lana derives state from an event stream rather than mutable database rows Auditability

Auditability Is Built Into the Data Model

In regulated financial systems, auditability is mandatory.

Institutions must be able to explain how balances changed, why credit decisions were made, and when transactions occurred. In most systems this is handled by a separate audit log that attempts to record what the main system did.

In practice, these logs drift from reality.

In Lana, our banking platform, the audit trail is the system itself.

Every state change is an event stored permanently with metadata such as timestamps, transaction identifiers, and contextual information. Because entities are reconstructed directly from those events, the audit record cannot diverge from the operational data.

There is no difference between the data used to run the system and the data used for compliance.

Investigations

Time Travel When It Matters

A common question in banking investigations sounds simple but can be difficult to answer precisely:

"What was the exact state of the system at the moment this transaction happened?"

Consider a fraud investigation.

A customer reports that a large transfer from their account was unauthorized. The transaction happened months ago and has now been escalated to law enforcement. Investigators need to understand exactly what conditions existed when the payment was processed.

Questions quickly extend beyond the transaction itself:

With event sourcing, the system can reconstruct the account exactly as it existed at that moment by replaying events up to that point in time.

This allows investigators to answer those questions with precision, based on the system's actual history rather than logs or approximations.

For fraud investigations, this level of accuracy reduces resolution time and improves outcomes for customers.

Reliability

Idempotency and Operational Safety

Retries are inevitable in distributed systems. What matters is whether they are safe.

In financial systems, a single incorrect retry can lead to duplicate transactions or inconsistent balances.

In Lana, our banking platform, commands are designed to be idempotent. Each operation determines from the event history whether it has already been applied and returns a result indicating whether it executed or was already handled.

This ensures that retries do not introduce inconsistencies, even under failure conditions.

Diagram illustrating idempotent command processing in an event-sourced system Evolution

Safer Evolution of Financial Products

Financial products evolve constantly. Regulations change, new features are introduced, and business models adapt.

In traditional systems, evolving an entity often requires database migrations and transformations of existing data.

With event sourcing, new capabilities are introduced by defining new event types. Existing entities simply do not contain those events.

For example, adding support for early loan repayment introduces new events. Loans created before that feature existed continue to behave exactly as before.

There is no need to backfill or modify historical data. The system evolves without putting existing data at risk.

The same event history also enables new projections such as reporting, analytics, and risk views without changing core entities.

Developer Experience

Making Event Sourcing Practical

The Real Cost of Event Sourcing

Event sourcing is powerful, but it is rarely adopted as a system-wide standard. Part of the reason is that it is less familiar than traditional approaches. More importantly, it is perceived as complex and costly to implement and maintain at scale.

A production-grade event-sourced system requires far more than storing events. Each entity needs infrastructure for event persistence, state reconstruction, concurrency control, querying, pagination, error handling, and transactional guarantees. Without strong abstractions, this leads to large amounts of repetitive and error-prone boilerplate.

This is where most implementations stop. Teams adopt event sourcing selectively for a few complex domains, while the rest of the system falls back to traditional patterns.

es-entity: A Reusable Foundation

To make event sourcing viable across the entire platform, we built es-entity, an open-source event sourcing library written in Rust.

The library moves this complexity out of application code and into a reusable foundation. Developers define the domain: the entity, its events, and the business logic. The rest is generated automatically at compile time.

From a minimal definition, the library provides:

Typed Repositories

Standard access and query methods, strongly typed at compile time.

Generated SQL

Common queries generated and verified at compile time. No hand-written SQL.

Concurrency Control

Optimistic locking based on event sequence numbers prevents conflicts.

Transactions

Multi-entity workflows with transactional guarantees across aggregates.

Idempotency

Built-in primitives that check event history before applying operations.

Error Handling

Structured errors with database constraint mapping for clear failure modes.

Querying Without Compromise

A common concern with event sourcing is how to query data efficiently.

To solve this, our platform Lana (through our event sourcing library, es-entity) maintains a query-optimized index per entity alongside the event stream. This index contains only the fields needed for lookups, filtering, and constraints, and is updated atomically with each event write.

This allows the platform to support efficient queries such as finding customers by email, listing facilities by status, or enforcing uniqueness constraints, without scanning event streams or compromising the event-sourced model.

Diagram showing how Lana queries event-sourced entities using a query index projection alongside the append-only event store

Developer Experience in Practice

In practice, developers do not write infrastructure code. They define events, implement state transitions, and express business rules. Idempotency, concurrency, and transactional consistency are handled as part of the underlying model rather than as ad hoc concerns.

This changes the economics of event sourcing.

Instead of requiring specialists and significant upfront investment per entity, the pattern becomes repeatable and consistent across the entire system. The complexity is still there, but it is isolated and solved once.

Without this level of automation, applying event sourcing consistently across a banking system is impractical.

Tradeoffs

The Tradeoffs

Event sourcing introduces upfront complexity. Developers must think in terms of event flows, and systems must handle eventual consistency in projections.

Another challenge is event evolution over time. Because events are immutable, changing or deprecating existing event types requires careful handling. Systems must maintain compatibility with historical events, and developers need to design for versioning and long-term schema stability.

However, financial platforms still need auditability, idempotency, historical reconstruction, and safe evolution. In traditional architectures these are implemented as separate systems and maintained over time.

Event sourcing provides these guarantees structurally.

The complexity appears earlier, but the system remains easier to extend and reason about as it grows.

Conclusion

A Platform Designed for the Long Term

By making history the source of truth, our banking platform Lana gains guarantees that are difficult to retrofit onto traditional architectures. For financial institutions building modern banking infrastructure, particularly those integrating Bitcoin and programmable financial systems, these properties are essential.

1

Full auditability: the audit trail is the operational data, not a separate system that can drift.

2

Historical reconstruction: replay events to any point in time for investigations, compliance, or debugging.

3

Safe retries: idempotent commands prevent duplicate transactions, even under failure conditions.

4

Additive evolution: new event types extend products without migrations or risking existing data.

As systems grow more complex, maintaining these properties as separate concerns becomes increasingly difficult. Event sourcing makes them part of the foundation. That is why, in our platform Lana, it is the standard across the entire system.

Stay Updated

Subscribe to the Bitcoin Banking Standard for monthly insights on Bitcoin banking trends and regulatory developments.