// the find
eugene-khyst/postgresql-event-sourcing
A reference implementation of an event-sourced system that uses PostgreSQL as an event store built with Spring Boot. Fork the repository and use it as a template for your projects. Or clone the repository and run end-to-end tests to see how everything works together.
A reference implementation of event sourcing on PostgreSQL using Spring Boot and Java 21. It solves the 'do I need a specialized event store?' question by showing exactly what it takes to implement reliable event ordering, snapshotting, optimistic concurrency, and the transactional outbox pattern on plain Postgres. Aimed at Java/Spring teams evaluating whether to adopt event sourcing without adding EventStoreDB or similar infrastructure.
The transactional outbox implementation is unusually thoughtful — it uses `pg_current_xact_id()` and `pg_snapshot_xmin()` to avoid the classic BIGSERIAL gap problem where fast-committed transactions can cause slower ones to be skipped. The core library is cleanly separated into its own Gradle subproject so the event sourcing machinery doesn't bleed into application code. Two outbox strategies are provided (transaction ID vs. table-level lock) with honest trade-off documentation, and LISTEN/NOTIFY support reduces polling overhead to near-zero when nothing is happening. The README is unusually complete, with ER diagrams, class diagrams, and SQL inline — rare for a reference project.
The sample domain (ride-hailing orders) is a short-lived aggregate, which sidesteps the hardest practical problem: snapshotting for long-lived, high-volume aggregates. The snapshotting code exists but it's exercised with a trivially small event count in the example, so you won't know if the strategy holds until you hit it in production. There's no event schema migration story — if an event's JSON shape changes, you're on your own for reading old events. The at-least-once delivery guarantee for integration events is acknowledged but there's no demonstration of an idempotent consumer, which is where most teams actually get burned.