ADR-001: Event Sourcing with Marten on PostgreSQL¶
Status: Accepted Date: 2026-03-09
Context¶
Tablez needs a full audit trail of all reservation state changes ("who changed what and when"). We need temporal queries ("what did the floor look like at 19:30?"), the ability to rebuild state from events, and event-driven cross-service communication.
Options Considered¶
| Option | Pros | Cons |
|---|---|---|
| Marten on PostgreSQL | Event store + document store in one DB, no extra infra, .NET native, projections built-in | Tied to PostgreSQL, smaller community than EventStoreDB |
| EventStoreDB | Purpose-built event store, excellent tooling | Extra infrastructure, separate database to manage, different query model |
| Custom event table in PostgreSQL | Full control, simple | No projection framework, rebuild manually, reinvent the wheel |
| Axon Framework | Enterprise features | Java ecosystem, heavy |
Decision¶
Use Marten as both event store and document store on PostgreSQL.
Rationale¶
- Zero extra infrastructure. PostgreSQL is already needed for read models. Marten uses the same database for events and projections.
- Inline projections update read models within the same transaction as the event append. No eventual consistency delay for critical paths.
- Strong .NET integration. First-class support for records, async, and DI.
- Proven at scale. Used in production by JasperFx and multiple enterprise systems.
- Migration path. If we outgrow Marten's event store, events in PostgreSQL are portable — standard JSONB columns.
Consequences¶
- All services that need event sourcing depend on PostgreSQL.
- Team must learn Marten's projection model (SingleStreamProjection, cross-stream projections).
- Schema management handled by Marten auto-create in dev, explicit migrations in production.