A Practical Guide for Building High-Scale, Audit-Friendly Systems
Event Sourcing is a powerful architectural pattern where the state of an entity is not stored directly. Instead, its state is rebuilt by replaying all the events that happened to it. As applications grow, replaying thousands of events for every request becomes slow. To solve this, we use Snapshot Optimization.
This article provides a full blueprint for designing event-sourced aggregates with snapshots, .NET implementation, and Angular UI integration, suitable for modern enterprise systems.
Introduction
Modern enterprise systems require:
Full auditability
Ability to rebuild previous states
High scalability
Non-destructive writes
Event Sourcing naturally provides this capability. Every change to an entity becomes an event, and the current state is a result of replaying all events.
But when you have thousands of events per entity, rebuilding state becomes expensive. This is where Snapshots come in.
What Is Event Sourcing?
Event Sourcing stores every state change as an event.
Example: Instead of updating a balance field:
Balance = 10000 → 12000You store:
Deposited 2000
Withdrawn 500
Fee Applied (50)
Interest Applied (300)
Current balance is computed from events.
What Is an Aggregate?
An Aggregate is a consistency boundary.
It ensures business rules are applied correctly.
Examples:
Order aggregate
User aggregate
Policy aggregate
Loan account aggregate
Aggregates hold:
Current state
List of uncommitted events
Logic to apply events
Why Event Sourcing Needs Snapshots
Replaying events is fine initially.
But for long-lived aggregates:
Thousands of events
Slow rehydration
More memory usage
High cold-start latency
Slower API responses
Snapshots store the latest computed state, so only recent events must be replayed.
Example:
Snapshot v100 → Replay events 101–120 onlyThis greatly improves performance.
Architecture Overview
┌────────────────────────┐
│ Angular UI │
│ (Commands + Queries) │
└─────────┬──────────────┘
│
▼
┌──────────────────────────────────────────┐
│ API Gateway / BFF │
└─────────┬────────────────────────────────┘
▼
┌────────────────────────┐
│ Aggregate Service │
│ (.NET) │
└──────┬─────────────────┘
│
▼
┌──────────────────────────────┬─────────────────────────────┐
│ Event Store (Append Only) │ Snapshot Store (SQL/Blob) │
└──────────────────────────────┴─────────────────────────────┘
Event Store vs SQL Store
| Event Store | Snapshot Store |
|---|---|
| Stores events only | Stores full aggregate state |
| Append-only | Point-in-time JSON |
| Immutable | Mutable |
| High write scale | Used rarely (read optimization) |

Join the conversation! Your thoughts help the community grow.