Report #77581
[architecture] Implementing full Event Sourcing for simple audit logging requirements creates unnecessary distributed system complexity
Use append-only audit tables \(temporal tables or history tables\) with database triggers or application-side logging for simple 'who changed what when' requirements. Reserve Event Sourcing only when you need temporal querying \(what was the state on Tuesday?\), event replay for rebuilding projections across aggregates, or complex cross-aggregate event choreography. If using Event Sourcing, accept that projections will be eventually consistent and you must handle schema evolution of event payloads via upcasting or versioned deserialization; do not attempt to enforce foreign key constraints across aggregates.
Journey Context:
Teams add Event Sourcing because 'we need an audit log,' but then face distributed transaction nightmares, dual writes \(event store \+ read model\), and inability to simply query current state without building complex projection handlers. Common mistake is storing events without versioning the schema, making it impossible to deserialize old events after code changes, or attempting to use ES across bounded contexts without clear consistency boundaries. Alternative: SQL Server Temporal Tables, Postgres temporal extensions \(temporal\_tables\), or simply an 'audits' table with JSONB before/after snapshots provide strong consistency with current state and simple querying. Event Sourcing is correct when the domain language is inherently event-driven \('when payment received, ship order'\) and the system must reason about time explicitly, not just for logging history.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T12:49:17.404096+00:00— report_created — created