Snapshots in Event Sourcing for Write Models

711 views
Skip to first unread message

Federico G

unread,
Sep 15, 2017, 2:52:48 PM9/15/17
to DDD/CQRS
Hello,

I'm interested in applying event sourcing in a small project. I was worried about the performance of rehydrating aggregates composed of several events, when I found this solution:

"If you are using event sourcing, you may be able to reduce the time it takes to load the state of an aggregate by using snapshots. Instead of replaying the complete event stream when you load an aggregate, you load the most recent snapshot of its state and then only play back the events that occurred after the snapshot was taken. You will need to introduce a mechanism that creates snapshots for aggregates on a regular basis. However, given the simplicity of a typical event store schema, loading the state of an aggregate is typically very fast. Using snapshots typically only provides a performance benefit when an aggregate has a very large number of events." (https://msdn.microsoft.com/en-us/library/jj591577.aspx)

My questions are:

1. Would you treat such as a snapshot as any other read model? (subscribe to events and normalize changes into the snapshot)
2. Would you find any issue with reusing the same snapshot for query purposes, as long as it serves both needs -read model and aggregate rehydration- at the same time? (I mean, in the case that if separated, the read models would be identical).

Alexander Langer

unread,
Sep 15, 2017, 3:23:31 PM9/15/17
to ddd...@googlegroups.com
> 1. Would you treat such as a snapshot as any other read model?
> (subscribe to events and normalize changes into the snapshot)

No.

> 2. Would you find any issue with reusing the same snapshot for query
> purposes, as long as it serves both needs -read model and aggregate
> rehydration- at the same time? (I mean, in the case that if separated,
> the read models would be identical).

Yes, we are actually doing this regularly (create a snapshot on every
write) with aggregates that are "nearly CRUD-like". Having a separate
projection (for the read model) that essentially copies the write
model's re-hydration code 1:1 is often pointless.

Best,
Alex






Federico G

unread,
Sep 15, 2017, 3:43:01 PM9/15/17
to DDD/CQRS
Thanks! Could you please elaborate on 1? How would creating a snapshot be any different than creating any other read model projection?

Alexander Langer

unread,
Sep 15, 2017, 4:15:16 PM9/15/17
to ddd...@googlegroups.com
A snapshot can serialize the current object's state. I'm not exactly
sure what you mean with "normalize changes into the snapshot", but I
don't see a purpose of subscribing to the events the aggregate just
emitted for the sole reason to recreate that very snapshot. (Isn't that
just a normal read model projection then anyways?).

Also, the (database) transaction semantics might differ (depends on the
use case). Snapshots that are taken to increase re-hydration speed can
be stored out of the write transaction after the write transaction
committed, as it's merely a cache (a failed snapshot write will only
cause the next re-hydration to take a bit longer). They can even be
held in memory.

If, however, the snapshot *is* the read model, you'll probably make sure
that either:

1) you save the events and the snapshot in the same transaction, or
2) you make sure that events are sufficiently retried if an error
occurs while updating the snapshot.

Option 2), however, is basically what the "normal" read model is
supposed to be doing, so that renders the whole snapshot-as-read model
approach pointless :-)

In my current project, we are using 1) for "CRUD style" aggregates:
Events are stored in the event table and the snapshot state is stored as
JSON, both in the same database transaction (Postgres). The snapshot is
used for the read.

HTH,
Alex
> --
> You received this message because you are subscribed to the Google
> Groups "DDD/CQRS" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to dddcqrs+u...@googlegroups.com
> <mailto:dddcqrs+u...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/dddcqrs.
> For more options, visit https://groups.google.com/d/optout.

Federico G

unread,
Sep 15, 2017, 4:42:49 PM9/15/17
to DDD/CQRS
Thanks a lot! I understand it now.

What do you mean with "CRUD style" aggregates? Are there aggregates were you would not be able to take the snapshot approach (as in "non-CRUD" aggregates)?

I was thinking that the snapshot would only be required for aggregates with several events, regardless of the aggregate style (if it can be event sourced, it should be "snapshotable", am I right?).

Greg Young

unread,
Sep 15, 2017, 4:55:52 PM9/15/17
to ddd...@googlegroups.com

I was thinking that the snapshot would only be required for aggregates with several events, regardless of the aggregate style (if it can be event sourced, it should be "snapshotable", am I right?). 

You should benchmark how many events you can load quickly, you might be surprised. Snapshots introduce versioning problems and this needs to be weighed against the performance gains.

To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.

Visit this group at https://groups.google.com/group/dddcqrs.
For more options, visit https://groups.google.com/d/optout.



--
Studying for the Turing test
Reply all
Reply to author
Forward
0 new messages