Granular events

When building a CRUD interface in an event sourced system, you'll come across the dilemma of how granular your events should be. Should you have a large PostUpdated event, or granular TitleUpdated, ContentUpdated, and AuthorUpdated events?

The main benefit of single, large events are how straightforward they are. Little code required. One event, one method on the aggregate root, one projector.

Besides that, granular events win.

Large events store unnecessary data. A single event always stores all data, even when unchanged. If I update a post's title, the PostUpdated event will contain the content and author as well. Granular events only contain the data that changed.

Large events can be difficult to change. If you add a property, you need to ensure old events don't break when they're deserialized. Granular events change less often. You'd add a new event for a new property, or stop dispatching an event for an old one.

Large events are difficult to react to. If I want to react to a title change, the PostUpdated event is not enough, as I don't know if the title actually changed. To know whether something changed, you need to query the current state in the aggregate root or projections. Granular events are only dispatched when something changed.

If the data is not critical or most importantly you don't plan to react to, large events are fine. Otherwise, granular events are the more versatile choice.