TechTrailCamp
← Back to Blog

Event Sourcing: Building Audit-Ready Systems

EVENT SOURCING Traditional: Store Current State account_id name balance A-001 Alice $750 How did we get to $750? No history. Event Sourcing: Store Every Change seq event_type data timestamp 1 AccountCreated {name: "Alice"} 10:00 2 MoneyDeposited {amount: 1000} 10:05 3 MoneyWithdrawn {amount: 200} 11:30 4 MoneyWithdrawn {amount: 50} 14:00 Replay: 0 + 1000 - 200 - 50 = $750 Complete audit trail. Time-travel to any point. Events are immutable — never updated or deleted Event sourcing = storing facts about what happened, not opinions about current state You can always derive current state from the event history, but you can never derive history from current state

In a traditional system, you store the current state of an entity. An account has a balance of $750. But how did it get there? Was it one deposit? Ten deposits and five withdrawals? Was a refund processed? The current state tells you nothing about the journey.

Event sourcing flips this model: instead of storing current state, you store every event that happened to the entity. The current state is derived by replaying these events. Every change is an immutable fact in an append-only log.

How It Works

  1. Command arrives — "Withdraw $200 from account A-001"
  2. Validate against current state — replay events to get current balance, check sufficient funds
  3. Append new event — store MoneyWithdrawn {amount: 200} in the event store
  4. Update projections — publish event to update read models, notifications, analytics

Why Event Sourcing?

1. Complete Audit Trail

Every state change is recorded as an immutable event with a timestamp and the user who triggered it. For financial systems, healthcare, and compliance-heavy domains, this is invaluable. You don't need to build a separate audit log — the event store is the audit log.

2. Time-Travel Debugging

Replay events up to a specific timestamp to see exactly what the state was at that point. A customer claims their order was cancelled incorrectly? Replay the events and see exactly what happened.

3. Retroactive Bug Fixes

Find a bug in how totals were calculated? Fix the projection logic, replay all events, and the read model is corrected — without modifying any source data.

4. Event-Driven Integration

Events are naturally publishable. Other services subscribe to your events to maintain their own views. This decouples services without shared databases.

Event Store Implementation

Event Store on AWS Command Lambda DynamoDB PK: aggregate_id SK: event_sequence DDB Stream + Lambda Read Model (ES) Notifications Analytics DynamoDB: append-only writes. Stream fans out to multiple projections.
DynamoDB as an event store with Stream-based projections
// Event store schema (DynamoDB)
// PK: ACCOUNT#A-001  SK: EVENT#00001
// PK: ACCOUNT#A-001  SK: EVENT#00002
{
  "pk": "ACCOUNT#A-001",
  "sk": "EVENT#00003",
  "eventType": "MoneyWithdrawn",
  "data": { "amount": 200, "reason": "ATM withdrawal" },
  "timestamp": "2026-02-10T11:30:00Z",
  "userId": "user-42",
  "version": 3
}

Snapshots: Performance Optimization

An account with 10,000 events takes time to replay. Snapshots solve this: periodically save the current state as a snapshot event. To rebuild state, load the latest snapshot and only replay events after it.

// Rebuild state with snapshot
Snapshot snapshot = eventStore.getLatestSnapshot("ACCOUNT#A-001");
List<Event> recentEvents = eventStore.getEventsAfter("ACCOUNT#A-001", snapshot.getVersion());

AccountState state = snapshot.getState();
for (Event event : recentEvents) {
    state = state.apply(event);
}
// state is now current

Event Sourcing + CQRS

Event sourcing pairs naturally with CQRS. The event store is the write model. Events are projected into read-optimized stores (Elasticsearch, Redis, PostgreSQL materialized views). This gives you the best of both worlds: complete audit trail on the write side, fast queries on the read side.

Common Pitfalls

  • Event schema evolution — events are immutable, but your code evolves. Use versioned event schemas and upcasters to handle old event formats.
  • Large event streams — without snapshots, replaying thousands of events is slow. Implement snapshotting early.
  • Treating events as commands — events describe what happened ("OrderPlaced"), not what should happen ("PlaceOrder"). This distinction matters for naming and semantics.
  • Deleting events — never delete events. If you need to "undo" something, append a compensating event ("MoneyRefunded"). For GDPR, use crypto-shredding (encrypt personal data with a key, delete the key).

When to Use Event Sourcing

  • Financial systems — every transaction must be auditable. Event sourcing is a natural fit.
  • Healthcare / compliance — regulatory requirements for complete data history.
  • Collaborative editing — Google Docs-style systems where multiple users make changes.
  • Complex business processes — order management, insurance claims, booking systems with many state transitions.

When NOT to Use Event Sourcing

  • Simple CRUD — if you just need to store and retrieve records, event sourcing is massive overkill.
  • No audit requirements — if nobody asks "what happened and when," you don't need the history.
  • Small teams — the operational complexity requires a team comfortable with eventual consistency and event-driven architectures.
Event sourcing doesn't add information to your system — it stops you from throwing information away. Every traditional UPDATE or DELETE discards history. Event sourcing preserves it.

Conclusion

Event sourcing is a powerful pattern for systems that need complete audit trails, time-travel capabilities, and event-driven integration. Combined with CQRS, it provides both a reliable write model and flexible read models. Start with a simple DynamoDB event store, add snapshots when performance requires it, and use DynamoDB Streams to project into read-optimized stores.

At TechTrailCamp, event sourcing and CQRS are covered in our Architecture and AWS tracks. You'll build real event-sourced systems with DynamoDB and Lambda through hands-on, 1:1 mentoring.

Want to build audit-ready, event-sourced systems?

Join TechTrailCamp's 1:1 training and master event sourcing on AWS.

Start Your Learning Journey