Transactional Audit Emission
also called Audit in the Same Transaction, Complete Audit Guarantee
Writing the audit record in the same transaction as the state change it describes, so that a crash cannot produce a change with no record - the property that distinguishes an audit trail from application logging.
Application logs are lossy by design: buffered, rotated by volume, dropped under pressure, and reshaped whenever a developer edits a message. An audit record is a durable business artefact with a schema, a retention policy and an owner, and it must be complete for its defined scope.
Emitting it in the same transaction as the state change is what makes it complete. Emitting it afterwards means a crash between the two produces a state change with no record — which is precisely the condition an auditor is testing for.
Why it matters
A regulator's question is not "do you log" but "can you demonstrate that every occurrence was recorded". An audit trail with an unknown number of gaps cannot support that claim, and the gap is by definition around the events that coincided with failure — the interesting ones.
Implementation patterns
- Same transaction as the state change, using an outbox row if the audit store is separate, so publication is atomic with the change.
- Append-only and immutable, including against administrators — write-once storage or a cryptographic chain, not a table with an update permission.
- Absence detectable via sequence numbers or chaining, since a log that can silently lose entries provides no assurance.
- Attributable to a person, not a service account. The human actor must propagate through every layer of automation, because "the batch job did it" is not an answer.
- Timestamped from a trusted source, since a clock an operator controls undermines the ordering.
- Capture what is usually missed: read access to sensitive data, authorisation denials, administrative and configuration changes, and the reason where judgement was exercised — an override, an exception, a manual adjustment — since intent cannot be reconstructed from a state change.
- Keep personal data out of the immutable record behind a pseudonymous reference, so an erasure obligation can be met by tombstoning the reference without breaking integrity.
Industry example
Regulated brokerages such as Groww and payment institutions such as Razorpay must reconstruct, years later, who did what on whose authority. The design consequence is that the audit path is engineered rather than inherited: it has its own schema, its own storage with its own retention, its own access controls, and its own tests.
The erasure tension is genuine and unavoidable in consumer financial products, and the identity separation must be in the first version — retrofitting it means rewriting every audit record ever written.
Failure scenarios
- Audit emitted after the state change, producing gaps exactly at failures.
- Audit as a log line, subject to buffering, rotation and format drift.
- Mutable audit storage, so the record cannot be relied on.
- Service-account attribution, defeating the purpose.
- Personal data embedded in immutable records, making erasure impossible without destroying the trail.
- No absence detection, so completeness is an assumption.
Trade-offs
Writing audit synchronously in the transaction adds latency and write volume to the hot path, and it couples the business operation to the availability of the audit mechanism. For very high-throughput operations that cost is real.
The mitigation is an outbox row rather than a remote write — cheap, local, atomic — with asynchronous publication afterwards. That preserves the completeness guarantee without putting a second system on the critical path, and it is the pattern that makes the requirement affordable.
Interview question
"An auditor asks you to prove that every privileged action in the last two years was recorded. What in your architecture supports that claim, and where would you expect to find gaps?"