5. Karma

You run UPDATE accounts SET balance = 900 WHERE id = 42. The row updates. A moment ago the number in that row was 1000, and now it is gone. Not archived, gone. How it got to 1000, when it changed, what moved it: none of that survives, unless a trigger or an audit table happened to be watching. The database keeps the answer and forgets the question.

Karma is one of the most borrowed words in English, and one of the most flattened. It usually arrives as cosmic bookkeeping. Do good and good returns, do harm and harm finds you, what goes around comes around. That reading is not so much wrong as sentimental. The older meaning is plainer and stranger.

Karma is Sanskrit for action, and also for the result the action leaves behind. One word carries both. The Bhagavad Gita’s teaching on it is causal, not moral. Every action produces a result. The result may land at once or wait years, but the chain from act to consequence is unbroken. Krishna states it to Arjuna in the second chapter, in the line most often quoted from the whole text: karmaṇy evādhikāras te mā phaleṣu kadācana. Your right is to the action alone, never to its fruits.

Shankara, commenting on that verse, is blunt about the mechanism. If you act thirsting for the result, he writes, you will have to reap those fruits. The fruit is not a reward you might earn. It is a consequence you cannot decline. You act, and you do not get to opt out of what the action set in motion.

Conventional software throws the consequence away. The default way we store state is to overwrite it. A row holds a value, you compute a new value, you write it in place. UPDATE ... SET. The old state is not moved or marked. It is replaced, and replacement is destruction.

This feels natural, because it matches how we think about the present. The balance is 900. Why keep 1000 around when it is not true anymore? But the balance was never the truth. The truth is the sequence of actions that produced it: opened, deposited, withdrew. The number 900 is only where that sequence has arrived so far. Overwrite it and you keep the arrival and destroy the journey, and with the journey goes every question of how and when and why that a future auditor, or the engineer paged when it breaks, will need to ask.

Karma names exactly what the overwrite discards. The action and its result are one thing, and the result is not yours to erase.

Event sourcing keeps the journey. Instead of storing the current state and writing over it, you store the actions themselves, in order, as immutable events. AccountOpened, Deposited(1000), Withdrew(100). The current balance is not a column you update. It is a fold over that list, computed by replaying the events from the start. Nine hundred is derived, and re-derivable at any point in the past you care to ask about.

Nothing is overwritten, because there is nothing to overwrite. A correction is not an edit. If the withdrawal was wrong, you do not reach back and change it. You append another event, a reversal, and the fold accounts for both. The log only grows. The past, once written, stays written.

And here the Gita says something a database architect would recognize. Your right is to the action, never to the fruit. Two different words carry the two halves: adhikāra, the right that attaches to the act, and phala, the fruit, which does not. Event sourcing, paired with CQRS, draws the same line between the write side and the read side. You own the event. You do not own the projections built from it. A payment service appends PaymentCaptured, and its responsibility ends at the fact, not at what gets folded from it. What the ledger, the receipt email, the analytics rollup, and the fulfillment queue each build out of that event is their concern, not the producer’s. Write the fact well and release the result. The Gita drew that boundary between action and fruit centuries before we rediscovered it in our storage engines.

State is a story, not a snapshot. You don’t overwrite the past, you append to it.

This is not an instruction to event-source everything. The pattern earns its cost in specific places, anywhere the history is the product: a bank ledger, a version control system, a collaborative editor where two people’s edits have to merge without one clobbering the other, an audit trail a regulator will read. Anywhere you will need to ask what the state was, not only what it is. Debugging by replay, stepping the events forward to reproduce a failure exactly as it happened, can pay for the whole thing on a bad day.

And it does have a cost. Events are a schema you can never fully retire, because the old ones are already written and you still have to read them. Rebuilding current state by replaying millions of events is slow, so you snapshot and cache, and now you maintain the fold as well as the log. Enforcing an invariant, a balance that must never go negative, means replaying the account, checking, and appending under an expected-version guard, or two concurrent writers race and one of them loses. State derived asynchronously from a stream is eventually consistent, and “eventually” is a word that has ruined afternoons. Sometimes you genuinely need the fruit before you go on: a payment must clear before you ship the goods, and no amount of architectural non-attachment changes that. The write and read split is a stance a design can take, not a law it must obey.

Even databases that present a mutable face often append underneath. Postgres does not overwrite a row on update. It writes a new version, marks the old one dead, and a later vacuum reclaims the space. Which is the honest limit of the whole idea. The log is sacred right up until retention, or storage cost, or a court order says otherwise. The right to erasure in the GDPR is the law reaching into the immutable record and requiring you to remove a person, and event-sourced systems have spent real engineering years learning to obey it without lying about the rest of the history. Immutability here is something you choose, and choices have their exceptions. Keep the log append-only by default, and know exactly where you break it.

The oldest event-sourced system is the one accountants have run for five centuries. Double-entry bookkeeping was set down in print by Luca Pacioli in 1494, and its first rule is the one event sourcing rediscovered: you never erase an entry. A mistake in the books is not fixed by reaching back and changing a number. You post another entry that reverses it, and both stay on the record. The balance is a fold over the journal. An auditor can walk the entries from the beginning and see not just where the money is but every action that moved it. The reason the books are trusted is precisely that you cannot quietly rewrite them.

Martin Fowler wrote event sourcing up as a software pattern in 2005 and reached for the same analogy, because it is the same idea. The version at modern scale is the log. Jay Kreps, then at LinkedIn, argued in 2013 that an append-only, ordered log is the abstraction sitting under databases, replication, and stream processing, and Kafka is built on that claim. A Kafka topic is the journal. Producers append and own the write. Consumers fold the log into whatever projection they need, each at its own pace, each owning its own read. Pacioli and Kreps are five hundred years apart and describing the same discipline: record the action, never overwrite it, derive the rest.

The UPDATE that opened this essay is still the right call most of the time. Most state does not need its history, and keeping every event forever is its own kind of hoarding. The point was never to stop overwriting. It is to see what you destroy when you do. Not a number, but the record of an action, and actions are the one thing you do not get to take back. That is most of what karma meant, before it became a slogan about cosmic payback.

Further Reading

The verse is Bhagavad Gita 2.47, with 2.48 close behind it on evenness toward the result. Eknath Easwaran’s translation (Nilgiri Press, 1985) is the most readable in English; A. Mahadeva Sastry’s The Bhagavad Gita with the Commentary of Sri Sankaracharya (1897, public domain) is the one to reach for when you want Shankara’s reading of adhikāra and phala. On the software side, Martin Fowler’s “Event Sourcing” (martinfowler.com, 2005) is the canonical write-up, and Jay Kreps’s “The Log: What every software engineer should know about real-time data’s unifying abstraction” (LinkedIn Engineering, 2013) is where the log becomes the point. For the five-hundred-year-old version, Luca Pacioli’s 1494 Summa de arithmetica holds the first printed account of double-entry bookkeeping.