Full Stack • Java • System Design • Cloud • AI Engineering

Event Sourcing Pattern - Complete Enterprise Guide

Learn the Event Sourcing architectural pattern with Spring Boot, Kafka, Event Store, CQRS integration, snapshots, replay, event versioning, and enterprise system design. Explore real-world banking, insurance, and e-commerce use cases with architecture diagrams.



Introduction

Most enterprise applications store only the latest state of data.

For example:

A customer changes their address.

Traditional databases simply update the record.

Before

Address = New York

↓

UPDATE

↓

After

Address = Texas

The previous value is lost unless auditing is implemented.

However, many industries require complete historical records.

Examples:

  • Banking Transactions
  • Insurance Claims
  • Healthcare Records
  • Financial Trading
  • Payment Systems
  • Logistics
  • E-Commerce Orders

Instead of storing the current state, Event Sourcing stores every business event that occurred.

The current state can always be reconstructed by replaying those events.


What is Event Sourcing?

Event Sourcing is an architectural pattern where:

  • Every business action is stored as an immutable event.
  • Events are never updated or deleted.
  • Current state is rebuilt by replaying events.

Instead of storing:

Account Balance = $800

Store:

Account Created

↓

Deposit $1000

↓

Withdraw $200

↓

Balance = $800

The balance is calculated from the event history.


Why Event Sourcing?

Imagine a banking system.

Customer actions:

  • Open Account
  • Deposit Money
  • Withdraw Money
  • Transfer Funds
  • Close Account

Instead of updating rows repeatedly:

Store every action permanently.

Benefits:

  • Complete audit history
  • Time travel
  • Replay
  • Debugging
  • Analytics
  • Regulatory compliance

Traditional CRUD

flowchart LR

CLIENT[Client]

CLIENT --> API[Spring Boot]

API --> DATABASE[(Current State)]

DATABASE --> API

Only the latest data exists.


Event Sourcing Architecture

flowchart LR

CLIENT[Client]

CLIENT --> API[Spring Boot]

API --> EVENTSTORE[(Event Store)]

EVENTSTORE --> PROJECTION[Projection]

PROJECTION --> READDB[(Read Database)]

Events become the source of truth.


Traditional Database Example

Customer Account

Account

Balance = $5000

After withdrawal:

Balance = $4500

Previous balance disappears.


Event Sourcing Example

Account Created

↓

Deposit $5000

↓

Withdraw $500

↓

Current Balance = $4500

Every business action remains permanently available.


Event Flow

sequenceDiagram

participant Customer

participant SpringBoot

participant EventStore

participant Projection

participant ReadDB

Customer->>SpringBoot: Deposit $100

SpringBoot->>EventStore: Store Deposit Event

EventStore-->>SpringBoot: Event Saved

SpringBoot->>Projection: Update Read Model

Projection->>ReadDB: Update Balance

Core Components

Command

Represents an intention.

Examples:

  • CreateAccount
  • DepositMoney
  • WithdrawMoney
  • PlaceOrder
  • ApproveClaim

Commands request changes.


Event

Represents something that already happened.

Examples:

  • AccountCreated
  • MoneyDeposited
  • MoneyWithdrawn
  • OrderPlaced
  • PaymentCompleted

Events are immutable.


Event Store

Stores every event.

Example:

Event Store

↓

AccountCreated

↓

Deposit

↓

Withdraw

↓

Transfer

The Event Store becomes the system of record.


Projection

Reads events and builds query-friendly data.

Example:

Events

↓

Projection

↓

Customer Balance

Applications query projections instead of replaying events every time.


Event Replay

Replay rebuilds application state.

flowchart LR
    STORE["Event Store"]
    REPLAY["Replay Engine"]
    PROJ["Projection Builder"]
    STATE["Current State"]

    STORE --> REPLAY --> PROJ --> STATE

Useful after failures or when introducing new projections.


Immutable Events

Events should never be modified.

Incorrect:

Deposit

↓

Change Amount

Correct:

Deposit

↓

Correction Event

↓

Current Balance

Corrections are represented by new events.


Event Versioning

Business requirements evolve.

Example:

Version 1

{
 "amount":100
}

Version 2

{
 "amount":100,
 "currency":"USD"
}

Use event versioning to support backward compatibility.


Snapshots

Replaying millions of events can be expensive.

Solution:

Snapshots.

Events 1–1000

↓

Snapshot

↓

Events 1001–1050

Recovery starts from the snapshot instead of replaying every event.


Snapshot Workflow

flowchart LR
    EVENTS["Events Stream"]
    SNAPSHOT["Snapshot Engine"]
    NEW["New Events"]
    STATE["Current State"]

    EVENTS --> SNAPSHOT --> NEW --> STATE

CQRS + Event Sourcing

CQRS and Event Sourcing are commonly used together.

flowchart TD
    CMD["Command"]
    HANDLER["Command Handler"]
    STORE["Event Store"]
    PROJ["Projection"]
    READ["Read Database"]
    QUERY["Query"]

    CMD --> HANDLER --> STORE --> PROJ --> READ --> QUERY

Commands modify data.

Queries read optimized projections.


Kafka Integration

Apache Kafka is commonly used for event distribution.

flowchart LR
    APP["Spring Boot Application"]
    KAFKA["Kafka"]
    STORE["Event Store"]
    CONSUMERS["Consumers"]

    APP --> KAFKA --> STORE --> CONSUMERS

Consumers build projections independently.


Event Store Options

Common technologies:

  • EventStoreDB
  • Apache Kafka
  • PostgreSQL
  • DynamoDB
  • MongoDB
  • Cassandra

The event store should support durable, ordered event storage.


Spring Boot Integration

Typical architecture:

  • Spring Boot
  • Kafka
  • Event Store
  • Projection Service
  • PostgreSQL

Pseudo Flow:

createOrder(){

publish(new OrderCreatedEvent());

}

Consumer:

@KafkaListener
public void consume(OrderCreatedEvent event){

projection.update(event);

}

Banking Example

Customer deposits money.

Account Created

↓

Deposit $500

↓

Deposit $1000

↓

Withdraw $300

↓

Balance = $1200

Every operation remains permanently stored.


Insurance Example

Claim Lifecycle:

Claim Created

↓

Documents Uploaded

↓

Survey Completed

↓

Approved

↓

Paid

Complete history available for audits.


E-Commerce Example

Order Lifecycle:

Order Placed

↓

Payment Completed

↓

Packed

↓

Shipped

↓

Delivered

Every state transition is an event.


Healthcare Example

Patient Journey:

Patient Registered

↓

Appointment Scheduled

↓

Diagnosis Added

↓

Prescription Issued

↓

Discharged

Provides complete medical history.


Enterprise Architecture

flowchart TD

CLIENT[Client]

CLIENT --> API[Spring Boot API]

API --> KAFKA[(Kafka)]

KAFKA --> EVENTSTORE[(Event Store)]

EVENTSTORE --> PROJECTION[Projection Service]

PROJECTION --> POSTGRES[(Read Database)]

POSTGRES --> DASHBOARD[Applications]

EVENTSTORE --> AUDIT[Audit System]

Advantages

  • Complete audit history
  • Event replay
  • Time travel
  • High traceability
  • Better debugging
  • Easy analytics
  • Event-driven integration
  • Regulatory compliance

Challenges

  • Increased complexity
  • Event versioning
  • Eventual consistency
  • Projection maintenance
  • Snapshot management
  • Storage growth
  • Learning curve

Event Sourcing vs CRUD

Feature CRUD Event Sourcing
Stores Current State Yes No
Stores History Limited Complete
Audit Trail Separate Built-In
Replay No Yes
Time Travel No Yes
Event Streaming Limited Excellent
Complexity Low Higher

Best Practices

  • Keep events immutable.
  • Design meaningful event names.
  • Store metadata with events.
  • Use snapshots for long event streams.
  • Version events carefully.
  • Build independent projections.
  • Make consumers idempotent.
  • Secure the event store.
  • Monitor replay and projection lag.
  • Archive historical events when appropriate.

Common Mistakes

❌ Updating existing events.

❌ Using events as mutable records.

❌ No snapshots.

❌ No event versioning.

❌ Large event payloads.

❌ Mixing commands and events.

❌ Ignoring replay testing.


Enterprise Use Cases

Banking

  • Ledger
  • Transactions
  • Transfers

Insurance

  • Claims
  • Policies
  • Renewals

Healthcare

  • Patient Records
  • Treatment History

Retail

  • Orders
  • Inventory
  • Shipping

Logistics

  • Shipment Tracking
  • Delivery Events

Interview Questions

  1. What is Event Sourcing?
  2. Why are events immutable?
  3. What is an Event Store?
  4. What are projections?
  5. What is event replay?
  6. Why are snapshots used?
  7. How does Event Sourcing differ from CRUD?
  8. How does CQRS complement Event Sourcing?
  9. What is event versioning?
  10. How would you implement Event Sourcing with Spring Boot and Kafka?

Summary

Event Sourcing is an architectural pattern where every business change is recorded as an immutable event rather than updating the current state directly.

A production-ready Event Sourcing architecture typically includes:

  • Spring Boot
  • Event Store
  • Apache Kafka
  • CQRS
  • Projections
  • Snapshots
  • Read Database
  • Monitoring and replay capabilities

This approach enables complete auditability, historical reconstruction, event replay, analytics, and seamless integration with event-driven systems. It is particularly valuable in banking, insurance, healthcare, logistics, and other domains where historical accuracy and traceability are critical.