Contents

Event Sourcing Pattern

Contents

Event Sourcing Pattern

It stores all changes to application state as a sequence of events rather than only saving the current state. This enables reconstruction of past states and provides a reliable audit trail.

  • Supports full history tracking and auditing, useful for compliance and debugging.
  • Ideal for financial systems where transactions and account histories must be reconstructed accurately.

Key concepts:

  • The Aggregate Root: In microservices, the “Aggregate” is the consistency boundary. For an Order service, the Order Aggregate ensures that you don’t “Ship” an order before it is “Paid.” It replays past events to calculate its current state before deciding if a new command is valid.
  • Snapshotting: If an aggregate has 10,000 events, replaying them all is slow. A Snapshot saves the state at event #10,000. The system loads the snapshot and only replays events that happened after it.
  • Event Versioning: In a long-running system, your event schema will change (e.g., adding a zipCode to an AddressUpdated event). You must handle Upcasting i.e. transforming old event formats into new ones during replay.

Java example using Axon:

@Aggregate
public class AccountAggregate {

    @AggregateIdentifier
    private String accountId;
    private double balance;

    // Command Handler: Logic to validate and create event
    @CommandHandler
    public AccountAggregate(CreateAccountCommand cmd) {
        apply(new AccountCreatedEvent(cmd.getId(), cmd.getInitialBalance()));
    }

    // Event Sourcing Handler: Logic to update state from event
    @EventSourcingHandler
    public void on(AccountCreatedEvent event) {
        this.accountId = event.getId();
        this.balance = event.getBalance();
    }
}

Event sourcing vs CRUD

FeatureCRUD MicroservicesEvent Sourced Microservices
Source of TruthCurrent state in a DBSequence of immutable events
HistoryNeeds separate audit tablesHistory is the data (native audit)
Data LossOverwrites previous valuesNo data is ever deleted/overwritten
QueryingDirect and simpleRequires Projections (CQRS)
ScalingScaling DB locks/contentionHighly scalable append-only writes