<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Event Sourcing on</title><link>/tags/event-sourcing/</link><description>Recent content in Event Sourcing on</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sun, 24 Nov 2024 00:00:00 +0000</lastBuildDate><atom:link href="/tags/event-sourcing/index.xml" rel="self" type="application/rss+xml"/><item><title>Lesson 3: CQRS + Event Sourcing Together — When the combination makes sense</title><link>/post/fundamentals/es-cqrs-together/</link><pubDate>Sun, 24 Nov 2024 00:00:00 +0000</pubDate><guid>/post/fundamentals/es-cqrs-together/</guid><description>&lt;p&gt;CQRS and event sourcing are often discussed together, presented as a single package, and that conflation is responsible for a lot of unnecessary complexity in codebases that should have stayed simple. I&amp;rsquo;ve seen teams adopt both because they read a blog post, without being clear on why they needed either. I&amp;rsquo;ve also seen teams who should have used both and instead built elaborate workarounds that were essentially CQRS and event sourcing with worse ergonomics. The question isn&amp;rsquo;t &amp;ldquo;should I use CQRS and event sourcing?&amp;rdquo; — it&amp;rsquo;s &amp;ldquo;do I have the specific problems these patterns solve?&amp;rdquo;&lt;/p&gt;</description></item><item><title>Lesson 2: Projections and Read Models — Build any view from your event stream</title><link>/post/fundamentals/es-projections/</link><pubDate>Fri, 13 Sep 2024 00:00:00 +0000</pubDate><guid>/post/fundamentals/es-projections/</guid><description>&lt;p&gt;After I shipped the event-sourced account system, the first question from the product team was: &amp;ldquo;Can we have a page that shows all accounts that have been dormant for more than 90 days?&amp;rdquo; In a traditional system, this is a query: &lt;code&gt;SELECT * FROM accounts WHERE last_activity &amp;lt; NOW() - INTERVAL '90 days'&lt;/code&gt;. In event sourcing, there&amp;rsquo;s no &lt;code&gt;last_activity&lt;/code&gt; column — there&amp;rsquo;s an event stream. My first instinct was to query the event store directly, find the latest event per stream, and filter. It worked. Then they asked for the top 100 accounts by balance. Then active accounts by geography. Then a real-time dashboard with all of the above simultaneously. Querying the event store for each of these is either very slow or very complex. The answer is projections — pre-computed read models built from your event streams.&lt;/p&gt;</description></item><item><title>Lesson 1: Event Store Design — Append-only logs that are your source of truth</title><link>/post/fundamentals/es-event-store/</link><pubDate>Sat, 29 Jun 2024 00:00:00 +0000</pubDate><guid>/post/fundamentals/es-event-store/</guid><description>&lt;p&gt;My first encounter with event sourcing was a financial system that needed a complete audit trail. The business requirement was clear: every change to an account balance had to be traceable — who changed it, when, why. The first approach was an audit log table alongside the main accounts table. We&amp;rsquo;d write to both in a transaction. Within six months, the audit table was out of sync with the accounts table. Bugs in the dual-write logic, a migration that updated account records without touching the audit log, a direct database fix that bypassed the application layer. The audit log was nearly useless. The core insight I eventually arrived at: the audit log shouldn&amp;rsquo;t be a secondary record — it should be the primary record. That&amp;rsquo;s event sourcing.&lt;/p&gt;</description></item></channel></rss>