advanced 3 min answer

A team adopts event sourcing for a billing service partly to get an audit log without extra work. Eighteen months later the internal audit function rejects the event store as audit evidence. The events are complete, immutable and never been modified. What is missing, and what does that tell you about the trade the team actually made?

event sourcingauditcomplianceschema versioningerasure
Show the full answer Hide the answer

What was gained, precisely

A complete, ordered, immutable record of what the system did, from which any past state can be reconstructed. That is genuinely valuable: debugging becomes possible for defects you cannot reproduce, and new read models can be built from history rather than from a backfill script.

What an audit log needs that an event log does not have

Who, under what authority, and from where. An event says InvoiceAdjusted {amount: -40.00}. An audit record must say which human or service principal requested it, which authorisation they held, which approval chain was followed, what the before and after values were, and the request's provenance — address, session, client.

Domain events are written for the benefit of the domain, so they carry the business fact and omit the actor. Retrofitting the actor is cheap for new events and impossible for the 18 months already written. The log is complete about the system and silent about accountability, which is the one property audit is buying.

Two further gaps appear in review:

  • Schema versions. Events written in 2025 use fields that were renamed in 2026, and the reconstruction code upcasts old events into the new shape. Reading the log therefore requires running the team's code, so the evidence is not self-describing and its interpretation is controlled by the party being audited.
  • Erasure. A data subject exercises a deletion right. The event log is immutable by design, so the usual answer is crypto-shredding — encrypt personal fields per subject and destroy the key. That works and it means the historical record can no longer be fully reconstructed, which undermines the completeness claim the audit case rested on.

What the team paid

Event sourcing is a permanent commitment with real recurring cost: every projection must be rebuildable, replays must be deterministic, schema evolution needs upcasters maintained forever, and snapshot management becomes an operational concern. A full rebuild of a projection over a billion events is hours of wall-clock time, and that number is the one that decides whether you can fix a projection bug quickly.

They paid all of that, and for audit they got a head start rather than a deliverable.

When the bill arrives

At the first external audit, which is typically 12 to 24 months after launch — long enough that retrofitting the actor into historical events is not an option. It arrives a second time at the first erasure request, and a third time at the first projection rebuild under time pressure.

The cheaper alternative, stated honestly

A dedicated append-only audit table written in the same transaction as the business change, with actor, authority, before and after values, timestamp and request provenance, on a retention schedule agreed with audit. It is perhaps a week of work, it is self-describing, it survives erasure of the operational record because it can be separately classified, and it does not constrain the rest of the design.

Choose event sourcing when reconstructing past state or rebuilding read models is a product requirement. Choose an audit table when the requirement is accountability. The two look similar on a whiteboard and are different artefacts, and doing both is normal.

Common weak answers

  • "Add the actor to the event payload." Right for the future and no help for the history that audit is examining, which is the whole problem.
  • "The events are immutable, so they are auditable by definition." Immutability is necessary and nowhere near sufficient. An unsigned immutable log written by the audited system proves only that nobody bothered to change it.
  • "Export the log to a warehouse for auditors." It moves the same missing fields somewhere else, and adds a transformation step whose correctness the auditor must now also trust.