DBRaven
Pattern · consistency

Event Sourcing

mature

Summary

Store every state change as an immutable, ordered event appended to an event store; derive current state by replaying the event log rather than overwriting rows in place.

Problem

Applications that mutate state in-place lose the history of how that state was reached, making audit trails, temporal queries, and downstream event-driven integration require additional infrastructure that is tightly coupled to the write path.

Description

In conventional CRUD systems a row is updated in-place and its history is lost. Event sourcing inverts this: each state transition is recorded as a named, typed event (e.g., OrderPlaced, PaymentConfirmed, OrderShipped) appended to an append-only event store. No event is ever mutated or deleted. The current state of any aggregate is derived by loading its event stream and folding events left-to-right through a pure reducer function.

The event store is the single source of truth. Read models (projections) are derived views built by consuming the event stream and materialising whatever shape downstream consumers need. A single event stream can feed many independent projections: a relational summary table, a search index, a cache, or an analytics warehouse. Projections can be rebuilt from scratch at any time by replaying the full event stream: a property conventional databases cannot offer.

Snapshots are a standard optimisation: after N events the aggregate state is serialised and stored so replays start from the snapshot rather than event 0. Without snapshots, aggregates with millions of events incur O(N) replay cost on every load. Snapshot frequency is tuned per aggregate based on event rate and acceptable load latency.

Event streams also enable temporal queries (what was the state at time T?), audit trails with zero additional instrumentation, and retroactive projection: building a new read model that queries history that already exists. These capabilities are impossible to retrofit onto a mutation-based schema.

Tradeoffs

Audit trail
+1.0

Complete immutable history of every state change at zero extra cost

Temporal queries
+0.9

Point-in-time reconstruction is native to the model

Write simplicity
+0.7

Append-only writes are low-contention and fast

Read complexity
-0.7

Every query requires a projection; no direct SQL over current state

Operational complexity
-0.6

Snapshot strategy, projection rebuild, and schema evolution are non-trivial

Debugging
+0.5

Failure is reproducible by replaying events to the point of failure

Schema evolution
-0.5

Event schema changes require versioned upcasters; breaking changes are painful

When to use

Domain requires a full audit trail of state transitions

Financial, compliance, and legal domains need immutable records of every change; event sourcing provides this without additional audit log tables

Multiple downstream systems must react to state changes

The event stream acts as an integration bus; consumers subscribe independently without coupling to the write path

Temporal queries (state at a past point in time) are a product requirement

Replaying to a point-in-time is trivial with an event log; impossible with a mutation-based schema unless CDC was wired separately

Domain logic is naturally expressed as commands and events

DDD aggregates map directly onto event streams; forcing CRUD onto a rich domain model produces impedance mismatch

When not to use

Domain state transitions are simple CRUD with no meaningful history

The projection and replay machinery adds operational overhead that is not justified when there is no need for history or derived views

Team has no experience with event-driven systems or DDD

Event sourcing requires a significant shift in mental model; onboarding cost is high and failure modes are non-obvious without experience

Query patterns require ad-hoc joins across many aggregates

Cross-aggregate queries require materialised projections; if queries are exploratory and unpredictable, a relational schema is more flexible

Operational Requirements

mandatory

Implement snapshot strategy for aggregates with >10,000 events

Without snapshots, replay cost is O(event_count); aggregates with high event rates will have unacceptable load latency after months of operation

mandatory

Design event schemas with forward-compatible versioning from day one

Events are immutable and permanent; upcasters must handle old event versions; breaking schema changes require migration of the entire event log

recommended

Monitor event store growth and plan partitioning or archival strategy

Event stores grow unboundedly; define retention and archival policy before the store reaches operational thresholds (>100M rows for PostgreSQL)

recommended

Build projection rebuild tooling and test it regularly

Projections are disposable; the ability to rebuild any projection from the event store is a core operational capability and must be exercised

Characteristics

Scales on
read
Implementation complexityhigh
Operational complexityhigh
Scaling ceilingThe event store grows without bound. Aggregates with event rates above ~10,000 events per second per partition require partitioned event stores (Kafka topics partitioned by aggregate ID). PostgreSQL as an event store is practical up to ~500M events per table before table scan cost for aggregate replay becomes significant and snapshot strategies become mandatory. Cross-aggregate queries require purpose-built projections; ad-hoc SQL joins are not available.

Technologies

Canonical

postgresqlkafkaredis

Alternatives

eventstore dbaxon frameworkmarten

Relationships

Complements

cqrsoutbox patterndatabase per servicewrite ahead log cdc

Conflicts with

two phase commit

Basis

Widely deployed in financial and e-commerce systems with well-documented operational characteristics; snapshot and schema evolution challenges are real and well understood

Related Architecture Knowledge

Outbound: this entity affects

ComplementsPattern
cqrs
Grounded

Event sourcing naturally produces a normalized write model (the event log) that CQRS separates from purpose-built read models (projections). Each pattern addresses what the other lacks: event sourcing provides audit and temporal query; CQRS provides fast reads without replay cost.

Tradeoffs

  • ·Two models to maintain: event schema evolution affects both command handlers and projection logic
  • ·Projection rebuild (full event replay) can take hours for mature systems with large event logs
  • ·Debugging requires correlating commands, events, and projection state across three separate stores
Full relationship →
ComplementsPattern
database per service
Grounded

Event sourcing and database-per-service reinforce each other: each service owns its event log and materializes its own read models independently, with cross-service data sharing happening via published events rather than shared database access.

Tradeoffs

  • ·Cross-service queries require eventual consistency: no joins across service event logs
  • ·Event schema versioning is a distributed coordination problem: schema changes require coordinated deployment
  • ·Debugging cross-service workflows requires distributed tracing (correlation IDs across event boundaries)
Full relationship →
Introduces RiskFailure Mode
long running transaction bloat
Grounded

Event-sourced systems that open a database transaction for the full event application cycle create long-running transactions that prevent VACUUM from reclaiming MVCC dead tuples.

Full relationship →

Inbound: affects this entity

Benefits FromWorkload
financial transaction workload
Grounded

Financial transaction workloads benefit from event sourcing because the event log provides an immutable audit trail, enables temporal queries (balance at any past date), and makes the derivation of current state fully traceable: meeting regulatory requirements that state-mutation databases cannot satisfy.

Tradeoffs

  • ·Event log growth is unbounded for long-lived accounts: snapshot and archival strategy required
  • ·Query complexity increases: current balance requires snapshot + replay, not a single SELECT
  • ·Schema versioning adds upcast complexity as event types evolve over years
Full relationship →
SupportsTechnology
kafka
Grounded

Kafka's durable, ordered, append-only log is the canonical infrastructure for an event store at scale. Topics with compaction or retention policies serve as the persistent event log that event sourcing requires.

Tradeoffs

  • ·Kafka does not support optimistic concurrency at the aggregate level natively: application must enforce sequence numbers
  • ·Event replay for a single aggregate requires filtering a partition by aggregate_id: not as efficient as a database query by aggregate_id
  • ·At-least-once delivery requires idempotent projection handlers
Full relationship →
SupportsTechnology
postgresql
Grounded

PostgreSQL serves as a capable event store for moderate event volumes, leveraging JSONB payloads, UNIQUE constraints for optimistic concurrency, and WAL-based replication as a natural CDC feed for downstream projections.

Tradeoffs

  • ·Single-table events at high insert rates creates WAL pressure and index bloat
  • ·Replaying a single aggregate requires filtering by aggregate_id: efficient with the right index but not a log seek like Kafka
  • ·Connection pool saturation is a risk when many projection consumers open long-lived connections
Full relationship →
ComplementsPattern
snapshot pattern
Grounded

Snapshots are a performance optimization for event-sourced aggregates, providing bounded aggregate load time without changing the event sourcing model.

Full relationship →
Informs GenerationPattern
write ahead log cdc
Grounded

Write-ahead log CDC is the technical substrate that enables event-driven downstream architectures. Understanding how WAL CDC works and its operational characteristics directly informs generation of event-driven patterns such as CQRS, event sourcing, and streaming pipelines built on database change capture.

Tradeoffs

  • ·WAL CDC adds load to the primary: each slot must track WAL independently
  • ·Dropped replication slot can cause disk exhaustion in hours under heavy write load
  • ·Schema evolution is a significant operational challenge for long-running CDC streams
Full relationship →

Used In Architecture Scenarios

Audit and Compliance Platformhigh

Financial Ledger

An append-only audit log architecture for capturing system actions: user operations, data access events, configuration changes, and financial operations: with cryptographic integrity chaining, immutable storage, and dual-path query serving. PostgreSQL stores the authoritative append-only event log in time-partitioned tables; ClickHouse serves historical aggregate queries and retention analytics; Kafka streams audit events in real time to SIEM integrations and security dashboards; Redis caches hot audit query results for compliance-facing read paths. No record is ever updated or deleted: only inserts are permitted. Each record includes a hash of the previous record, forming a tamper-evident chain verifiable without external tooling.

E-Commerce Order Platformhigh

Marketplace Platform

An e-commerce order lifecycle platform handling cart, checkout, payment, fulfillment, and returns across a mixed read/write workload where product discovery is read-heavy, checkout is write-transactional, and fulfillment is event-driven. The saga pattern orchestrates multi-step checkout: reserve inventory → charge payment → confirm order → notify fulfillment. PostgreSQL owns order records and inventory with row-level locking; Redis holds session state and cart contents with sub-millisecond access; RabbitMQ delivers fulfillment notifications with dead-letter handling; Elasticsearch serves product search and order history with faceted navigation. CQRS separates the write command path from the read model: the order read model is denormalized for fast order history queries without joining across domain tables.

Financial Ledger Platformexpert

Financial Ledger

A strict consistency financial architecture for double-entry accounting, payment processing, and audit trail management where every debit must have a corresponding credit, every state transition must be ordered and durable, and the complete history must be reconstructable without gaps. Event sourcing provides an append-only audit log; the outbox pattern guarantees at-least-once downstream event delivery without distributed two-phase commit (idempotent consumers deduplicate on event ID for effectively-once processing); PostgreSQL provides ACID guarantees for ledger entry atomicity.

Gaming Backend Platformhigh

Realtime Collaboration

An online multiplayer game backend built around authoritative server game state synchronization. Game rooms run as distributed state machines where the server is the single source of truth for game state: client predictions are reconciled against the server state at every tick. WebSocket connections provide low-latency bidirectional communication for state deltas. Redis stores active game room state (in-flight, with sub-millisecond access), session affinity tokens (routing players to the same server instance as their game room), and matchmaking queues. PostgreSQL is the durable store for player profiles, persistent inventory, leaderboards, and achievement records. Kafka carries post-game event streams for analytics, anti-cheat processing, and achievement evaluation. NATS provides low-latency pub/sub for intra-cluster game state broadcasting when multiple game server instances must coordinate on shared state. Event sourcing records every game action as an immutable event for replay, dispute resolution, and anti-cheat audit.

Healthcare Records Platformexpert

Financial Ledger

An electronic health record (EHR) architecture built around strict auditability, HIPAA compliance, and append-only correctness. Clinical records are mutable by design (amendments, addenda) but corrections must be explicitly attributed, not silently overwritten. Event sourcing provides a reconstructable audit log; PostgreSQL row-level security enforces patient-level access control at the database layer; Kafka streams HL7 FHIR events to downstream clinical systems. The architecture must support breach detection, access auditing, and state reconstruction at any historical point: not just current state retrieval.

Streaming Media Platformhigh

Event-Driven System

A video and audio streaming architecture where content ingestion triggers an async multi-variant transcoding pipeline, CDN delivery handles 95%+ of playback traffic, and Cassandra absorbs the write volume of per-user viewing history. Kafka decouples upload events from transcoding workers; MinIO stores raw and encoded assets; Redis maintains playback session state and view counters. The architecture must handle upload spikes without blocking delivery, and cache cold starts without cascading database load.

Two-Sided Marketplace Platformexpert

Marketplace Platform

A two-sided marketplace architecture serving buyers, sellers, listings, transactions, search, and notifications from a shared infrastructure, where multiple independent domains must coordinate without tight coupling. Event sourcing captures every state transition; the saga pattern orchestrates multi-step transactions (create order, reserve inventory, charge payment, notify seller) with compensating transactions for partial failures. Kafka decouples domain event publication from consumption; RabbitMQ handles notification fanout; Elasticsearch serves listing search; Redis caches listing display and session state.

Event Sourcing: DBRaven