Report #11234
[architecture] Event Sourcing aggregate rehydration is too slow with thousands of events
Implement snapshots: store a denormalized copy of aggregate state every N events \(e.g., every 100 events\) or time-based. Load the latest snapshot first, then replay only events since that snapshot. Store snapshots in a separate table \(aggregate\_id, version, state\_json/state\_bytes, created\_at\). Invalidate/regenerate snapshots on schema changes \(version the snapshot serializer\).
Journey Context:
Loading an aggregate by replaying its entire event stream becomes linearly slower as the aggregate lives longer \(e.g., a bank account with 10 years of transactions\). This violates performance SLAs for read models. Snapshots trade storage for time: O\(1\) load time relative to total events, O\(N\_snapshot\) replay time. Alternative is CQRS with separate read models, but that adds eventual consistency complexity. Snapshots must be treated as opaque caches: they can be deleted and regenerated from events \(source of truth\), allowing schema migrations by rehydrating from events and storing new snapshot format. Common error: storing only the snapshot as source of truth, losing event history.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T12:49:17.103275+00:00— report_created — created