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

Event Sourcing Pattern in Java

Learn Event Sourcing Pattern in Java with Kafka, Event Store, Event Replay, CQRS integration, audit history, microservices architecture, banking examples, and interview questions.

What You Will Learn

  • What is Event Sourcing?
  • Why Event Sourcing is Needed
  • Event Store Architecture
  • Event Replay
  • Snapshot Pattern
  • CQRS + Event Sourcing
  • Kafka Integration
  • Banking Examples
  • Enterprise Use Cases
  • Benefits and Limitations
  • Interview Questions

Introduction

Traditional applications store only the latest state.

Example Bank Account:

Account Balance = $10,000

Database stores:

ACCOUNT
--------------------------------
ID      BALANCE
1       10000

Question:

How did balance become $10,000?

What transactions occurred?

Can we reconstruct history?

Traditional systems often cannot answer easily.

Event Sourcing solves this problem.


What is Event Sourcing?

Event Sourcing is an architectural pattern where every state change is stored as an immutable event.

Instead of storing:

Current State

Store:

History Of Events

Purpose of Event Sourcing

Primary Goal:

Store Every Change

As An Immutable Event

Traditional Database Approach

flowchart LR

A[Application]

B[Update Account Balance]

C[Database]

A --> B
B --> C

Only latest value exists.


Event Sourcing Approach

flowchart LR

A[Application]

B[Event Store]

A --> B

Store every business event.


Traditional Example

Bank Account:

Balance = 10000

We only know:

Current State

We do NOT know:

Deposit History

Withdraw History

Transfer History

Event Sourcing Example

Store events:

Account Created

Deposit 5000

Deposit 3000

Withdraw 1000

Deposit 3000

Current Balance:

10000

calculated from events.


Core Idea

flowchart LR

A[Command]

B[Generate Event]

C[Store Event]

D[Build Current State]

A --> B
B --> C
C --> D

What is an Event?

An event represents:

Something That Already Happened

Examples:

AccountCreated

MoneyDeposited

MoneyWithdrawn

OrderPlaced

ClaimApproved

Events are:

Immutable

Never modified.


Event Characteristics

Past Tense

Immutable

Business Meaningful

Time Ordered

Bank Account Example

Event 1:

{
  "event":"AccountCreated",
  "accountId":"123"
}

Event 2

{
  "event":"MoneyDeposited",
  "amount":5000
}

Event 3

{
  "event":"MoneyWithdrawn",
  "amount":1000
}

Event Store

Instead of:

ACCOUNT

Store:

EVENT_STORE

Event Store Structure

EventId

AggregateId

EventType

Payload

Timestamp

Event Store Architecture

flowchart LR

A[Commands]

B[Event Store]

C[Events]

A --> B
B --> C

Account Lifecycle

flowchart LR

A[Account Created]

B[Deposit 5000]

C[Deposit 3000]

D[Withdraw 1000]

E[Current Balance]

A --> B
B --> C
C --> D
D --> E

Event Replay

One of the biggest advantages.

Current state can be rebuilt by replaying events.


Replay Flow

flowchart LR

A[Event 1]

B[Event 2]

C[Event 3]

D[Rebuild State]

A --> D
B --> D
C --> D

Replay Example

Events:

Deposit 5000

Deposit 3000

Withdraw 1000

Replay:

0 + 5000

5000 + 3000

8000 - 1000

Result:

7000

Aggregate

Aggregate is the business entity.

Example:

Account

Order

Claim

Policy

Events belong to aggregates.


Aggregate Flow

flowchart LR

A[Account Aggregate]

B[Account Events]

A --> B

Snapshot Pattern

Problem:

Millions Of Events

Replay becomes slow.

Solution:

Snapshot

Store periodic state.


Snapshot Example

Event 1

Event 2

Event 3

Snapshot

Event 4

Event 5

Replay starts from snapshot.


Snapshot Architecture

flowchart LR

A[Events]

B[Snapshot]

C[Latest Events]

D[Current State]

A --> B
B --> D
C --> D

CQRS + Event Sourcing

Most common architecture.

Commands:

Generate Events

Queries:

Read Projections

CQRS + Event Sourcing Flow

flowchart LR

A[Command]

B[Event Store]

C[Projector]

D[Read Database]

E[Query]

A --> B
B --> C
C --> D
D --> E

Projection

Projection creates read models from events.

Example:

Order Events

↓

Customer Summary

↓

Dashboard

Projection Flow

flowchart LR

A[Events]

B[Projection]

C[Read Model]

A --> B
B --> C

Kafka Integration

Kafka works naturally with Event Sourcing.

Events become messages.


Kafka Architecture

flowchart LR

A[Command Service]

B[Event Store]

C[Kafka Topic]

D[Consumers]

A --> B
B --> C
C --> D

Spring Event Example

Event:

public record MoneyDepositedEvent(
        String accountId,
        Double amount) {
}

Event Handler

@Service
public class AccountProjection {

    public void handle(
            MoneyDepositedEvent event) {

        // Update Read Model
    }
}

Banking Example

Events:

AccountCreated

MoneyDeposited

MoneyWithdrawn

MoneyTransferred

Audit history becomes automatic.


Banking Architecture

flowchart LR

A[Transfer Command]

B[Event Store]

C[Account Events]

D[Read Database]

A --> B
B --> C
C --> D

Insurance Example

Events:

ClaimSubmitted

ClaimReviewed

ClaimApproved

ClaimPaid

Every step preserved forever.


Insurance Workflow

flowchart LR

A[Claim Submitted]

B[Claim Reviewed]

C[Claim Approved]

D[Claim Paid]

A --> B
B --> C
C --> D

Order Processing Example

Events:

OrderPlaced

PaymentCompleted

InventoryReserved

OrderShipped

OrderDelivered

Order Lifecycle

flowchart LR

A[Order Placed]

B[Payment Completed]

C[Inventory Reserved]

D[Shipped]

E[Delivered]

A --> B
B --> C
C --> D
D --> E

Event Sourcing Benefits

Complete Audit History

Every Change Recorded

Event Replay

Rebuild Entire System

Time Travel

View System State

At Any Point In Time

CQRS Friendly

Perfect Integration

Event Driven Architecture

Natural Fit

Limitations

❌ Complex Design

❌ Event Versioning

❌ Eventual Consistency

❌ More Storage Required

❌ Harder Debugging


Event Versioning Problem

Old Event:

{
 "customer":"Venu"
}

New Event:

{
 "customer":"Venu",
 "email":"[email protected]"
}

Need backward compatibility.


Event Sourcing vs Traditional CRUD

Feature CRUD Event Sourcing
Current State Yes Derived
History Limited Complete
Audit Trail Manual Automatic
Replay No Yes
Complexity Low High

Event Sourcing vs CQRS

Feature CQRS Event Sourcing
Read/Write Separation Yes Optional
Stores Events No Yes
Often Together Yes Yes

Enterprise Use Cases

Banking

Transactions

Account History

Audit Trails

Insurance

Claims

Policy Lifecycle

Compliance Tracking

Retail

Order History

Inventory Events

Trading Platforms

Trade Events

Portfolio Tracking

Healthcare

Patient History

Medical Records

Real Enterprise Architecture

flowchart LR

A[Client]

B[API Gateway]

C[Command Service]

D[Event Store]

E[Kafka]

F[Projection Service]

G[Read Database]

A --> B

B --> C

C --> D

D --> E

E --> F

F --> G

When To Use Event Sourcing

Use when:

Audit History Required

Complex Business Workflows

Banking Systems

Insurance Systems

Trading Platforms

Event Driven Architecture

When NOT To Use Event Sourcing

Avoid when:

Simple CRUD Applications

Small Systems

Low Audit Requirements

Interview Questions

What is Event Sourcing?

Store every state change as an immutable event.


What is Event Store?

Database that stores business events.


What is Event Replay?

Rebuilding state by replaying events.


Why Use Snapshots?

Improve replay performance.


CQRS Relationship?

CQRS often uses Event Sourcing.


Kafka Relationship?

Kafka commonly transports events.


Biggest Benefit?

Complete audit history.


Biggest Drawback?

Complexity.


Key Takeaways

  • Event Sourcing stores events instead of current state.
  • Every state change becomes an immutable event.
  • Supports audit trails, replay, and time travel.
  • Frequently combined with CQRS.
  • Kafka integrates naturally with Event Sourcing.
  • Widely used in Banking, Insurance, Trading, and Enterprise Systems.
  • One of the most advanced architecture patterns in modern distributed systems.