<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/event-sourcing-set-and-remove-based-bi-temporal-events-8de56bzad" -->

---
title: Event Sourcing: set-and-remove-based bi-temporal events
description: Part twelve of a series on event sourcing explores set-and-remove-based bi-temporal events, contrasting them with the previously covered lifetime...
canonical: https://daily.dev/posts/event-sourcing-set-and-remove-based-bi-temporal-events-8de56bzad
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Event Sourcing: set-and-remove-based bi-temporal events | daily.dev
og:description: Part twelve of a series on event sourcing explores set-and-remove-based bi-temporal events, contrasting them with the previously covered lifetime...
og:url: https://daily.dev/posts/event-sourcing-set-and-remove-based-bi-temporal-events-8de56bzad
og:image: https://api.daily.dev/og/posts/8DE56BzAD.png
og:image:alt: Event Sourcing: set-and-remove-based bi-temporal events
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

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

**[We Are .NET](https://daily.dev/sources/wearedotnet)** · 4 min read · 1 upvotes · 0 comments

## Summary

Part twelve of a series on event sourcing explores set-and-remove-based bi-temporal events, contrasting them with the previously covered lifetime (create-update-delete) variant. These events model timelines where data is assigned and removed over time rather than tracking a thing's full lifecycle. A key challenge introduced is the insert vs. override projection problem: when a new event is added with an earlier effective date than an existing event, the system must decide whether the new event overrides all later events or is inserted between them, preserving the later event's effect. Both behaviors are valid depending on context, so the projection must be configurable. A concrete example using organisational unit calendars in F# illustrates how to configure set-and-remove projection with override behavior.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.planetgeek.ch/2026/07/07/event-sourcing-set-and-remove-based-bi-temporal-events>

## Questions this post answers

### In event sourcing, what is the difference between override and insert behavior for bi-temporal events with earlier effective dates?

Override means a newly added event with an earlier effective timestamp than existing events replaces those later events going forward, while insert means the new event's value is only valid until the effective timestamp of the existing later event, preserving both. Both are valid depending on the business scenario, such as validation rule changes, so the projection logic needs to support choosing between them.

_Developers designing bi-temporal event projections can compare override versus insert tradeoffs through daily.dev._

### What is the difference between lifetime-based and set-and-remove-based bi-temporal event streams?

Lifetime-based (create-update-delete) events represent a thing's full lifespan, projected by sorting on effective timestamps with application timestamps breaking ties between simultaneous updates. Set-and-remove-based events instead represent a timeline of which data value is relevant at a given moment, such as calendar assignments or workday validation rule sets, without modeling an entity's creation or deletion.

_Teams modeling temporal data can weigh these event sourcing patterns while browsing daily.dev._

## Similar posts on daily.dev

- [Event Sourcing: undo set-remove-based bi-temporal events – because we must](https://daily.dev/posts/event-sourcing-undo-set-remove-based-bi-temporal-events-because-we-must-y6cpmwees) · We Are .NET · 0 upvotes · 0 comments
- [Event Sourcing: fun with bi-temporal timelines](https://daily.dev/posts/event-sourcing-fun-with-bi-temporal-timelines-znsnieuys) · We Are .NET · 0 upvotes · 0 comments
- [Event sourcing: non-bi-temporal events in a bi-temporal stream](https://daily.dev/posts/event-sourcing-non-bi-temporal-events-in-a-bi-temporal-stream-8scwvqj99) · We Are .NET · 0 upvotes · 0 comments
- [Event Sourcing: the not-so-simple bi-temporal basics](https://daily.dev/posts/event-sourcing-the-not-so-simple-bi-temporal-basics-t4ntaclgn) · We Are .NET · 0 upvotes · 0 comments
- [Fixing bugs in Event Sourcing is hard, for real?](https://daily.dev/posts/fixing-bugs-in-event-sourcing-is-hard-for-real--ardsmesga) · Architecture Weekly · 1 upvotes · 0 comments

---

Tags: [#architecture](https://daily.dev/tags/architecture), [#domain-driven-design](https://daily.dev/tags/domain-driven-design)

[View this post on daily.dev](https://daily.dev/posts/event-sourcing-set-and-remove-based-bi-temporal-events-8de56bzad)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Event Sourcing: set-and-remove-based bi-temporal events","url":"https://daily.dev/posts/event-sourcing-set-and-remove-based-bi-temporal-events-8de56bzad","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/event-sourcing-set-and-remove-based-bi-temporal-events-8de56bzad"},"datePublished":"2026-07-07T08:00:46.201Z","dateModified":"2026-09-14T07:11:58.693Z","description":"Part twelve of a series on event sourcing explores set-and-remove-based bi-temporal events, contrasting them with the previously covered lifetime...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/1b32daa3764f137a76f4fc32988a39ec?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/1b32daa3764f137a76f4fc32988a39ec?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"We Are .NET","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"We Are .NET","logo":"https://media.daily.dev/image/upload/s--BsnVOa3i--/f_auto/v1718347410/logos/wearedotnet","url":"https://daily.dev/sources/wearedotnet"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/event-sourcing-set-and-remove-based-bi-temporal-events-8de56bzad","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"architecture,domain-driven-design","timeRequired":"PT4M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"We Are .NET","item":"https://daily.dev/sources/wearedotnet"},{"@type":"ListItem","position":3,"name":"Event Sourcing: set-and-remove-based bi-temporal events"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/event-sourcing-set-and-remove-based-bi-temporal-events-8de56bzad#faq","mainEntity":[{"@type":"Question","name":"In event sourcing, what is the difference between override and insert behavior for bi-temporal events with earlier effective dates?","acceptedAnswer":{"@type":"Answer","text":"Override means a newly added event with an earlier effective timestamp than existing events replaces those later events going forward, while insert means the new event's value is only valid until the effective timestamp of the existing later event, preserving both. Both are valid depending on the business scenario, such as validation rule changes, so the projection logic needs to support choosing between them. Developers designing bi-temporal event projections can compare override versus insert tradeoffs through daily.dev."}},{"@type":"Question","name":"What is the difference between lifetime-based and set-and-remove-based bi-temporal event streams?","acceptedAnswer":{"@type":"Answer","text":"Lifetime-based (create-update-delete) events represent a thing's full lifespan, projected by sorting on effective timestamps with application timestamps breaking ties between simultaneous updates. Set-and-remove-based events instead represent a timeline of which data value is relevant at a given moment, such as calendar assignments or workday validation rule sets, without modeling an entity's creation or deletion. Teams modeling temporal data can weigh these event sourcing patterns while browsing daily.dev."}}]}
```

