There is a moment in Greg Young’s Code on the Beach talk from 2014 that I keep coming back to. He asks the room how many people have an UPDATE or DELETE statement in their system. Every hand goes up. Then he asks how many of them sat down with the CEO and the board to talk about how that data had no value. The hands come down.
I have watched that talk dozens of times, and I find something new in it every time. This point deserves far more attention than it gets: most teams have no idea how much information their CRUD systems destroy, because the destruction is invisible by design.
Two carts.
Picture two shopping carts in an online store. Customer A adds three items and checks out. Customer B adds four items, winces at the total, removes one, and checks out. In a typical CRUD schema, both orders now look the same. Three line items, one address, one total. Byte for byte identical. Two different customers, two different stories, one row.
Two different histories, one identical row. The removed item is the information the DELETE destroyed.
Greg tells the second story on himself. When his cart total climbs too high, he removes an item or two before checkout. He still wants those items. He wants them next month, after the credit card has cooled off. A removed item and a never-added item are different business facts: deferred desire on one side, no desire on the other. The DELETE statement collapses both into the same fact. Nothing.
A table stores conclusions.
This is the mechanism, and it applies to every structural model no matter how carefully designed. Current state is a derived value. It is what remains after applying every insert, update, and delete the record ever saw. Store only the result and you have thrown away the inputs. Whenever two different histories produce the same result (added then removed, changed then changed back, applied then reverted), the difference between them is gone. No backup will recover it. It was never written down.
Greg’s claim in the talk is blunt: event sourcing “is the only model that does not lose information.” Store the facts themselves (CartCreated, ItemAdded, ItemRemoved, CheckedOut) and current state becomes a function you run over them. You can delete and rebuild state whenever you like. You can never rebuild discarded facts from state.
The report that arrives a year late.
Here is where the loss stops being philosophical and starts costing money. A product manager comes to you and says: I want to know which items customers remove from their carts within five minutes of checkout, because I believe they buy those items later, and I want to remarket them.
In a CRUD system, the answer is a schema change. You add a removed_items table, deploy it, and start collecting. The report runs on day one and shows nothing, because it counts forward from the deploy. The first useful version of that report is a year away. The years of behavior your customers have already given you are gone for good.
The same report request, deployed the same day, on two architectures.
In an event-sourced system, ItemRemoved events have been accumulating since the day the system went live. You write a projection over the event log and the report covers the entire life of the system by Monday morning. Better still, you can answer what the report would have shown on any date in the past. The business asks a brand-new question and the system answers it retroactively. In my experience, the moment a stakeholder understands this is the moment the architecture conversation changes. They stop asking what the system stores and start asking what the business could learn.
Who approved the forgetting?
Every UPDATE overwrites a value that will never be seen again. Every DELETE removes a fact that was once worth recording. Which data a company remembers is a business decision. In CRUD systems that decision is made by a developer, inside a migration script, without a meeting. Nobody weighed those removed cart items against a future remarketing campaign and ruled them worthless. The schema had nowhere to keep them, and nobody noticed that a decision was being made at all.
That is the force of Greg’s question about the CEO and the board. The room laughs because the conversation he describes has never happened anywhere.
Older industries settled this centuries ago.
Ask your bank for your balance and it will add up your transactions. The balance is a derived number; the transactions are the record. Accountants correct a wrong entry by appending a reversing entry, and an erased line in a ledger is evidence of tampering. Your doctor appends to your chart rather than replacing last year’s picture of you. When Greg points out that no mature industry runs on current state, he is describing institutions that learned the hard way that history is the asset. Software is the young industry here. We made overwriting the default because storage was expensive in 1980, and we kept it as the default long after that argument died.
Count both costs.
Event sourcing is not free, and I will not pitch it as free. Event schemas become contracts you maintain for years. Read models bring eventual consistency you have to design for, and teams need time to stop thinking in rows. Weigh all of that. Then weigh the other side with the same rigor: a CRUD system spends every day quietly deciding, on your behalf, which questions your business will never be able to ask. You get to choose which bill you pay. You do not get to choose zero.
I am writing a book on Event Sourcing and CQRS, with a complete production-grade reference implementation in C# and .NET. The argument above gets a much fuller treatment there. More on that soon.