Event Sourcing: set-and-remove-based bi-temporal events

2026-07-18 · source · source ↗ · raw capture · wiki page

Part twelve of Enzler's event sourcing series. It contrasts two kinds of bi-temporal event streams: the "lifetime" kind (create-update-delete, covered in earlier posts) and "set-and-remove-based" events, where the timeline specifies which data is relevant at any given moment — like assigning or removing a calendar to an organizational unit, or an employee starting and stopping on a project.

Both kinds use two time axes: effective time (when something takes effect) and application time (when data was recorded). The key design choice is what happens when an event with a later application timestamp has an earlier effective timestamp. The system must support two behaviors: override (the new event wins for all effective dates) or insert (the new event applies only until the next event's effective date). Enzler argues both are valid, so projection behavior must be explicitly configured per stream.

The post walks through organizational calendars as a detailed example, defining set events (Sets(effective, value)) and remove events (Removes effective), with projection configured as SetRemove + OverrideBehavior.Override. The next post in the series covers reversing events in these timelines.