Contents
- Why this way of thinking feels close to me
- What does a system actually remember?
- I don't need to know all of tomorrow's questions today
- When the error is in the view, not in the history
- Events need context
- Memory has its price
- What this leads to in an application
- Why I keep coming back to this right now
- Where the comparison ends for me
- From understanding to internalizing
- Sources and further reading
Why this way of thinking feels close to me
When I try to understand a person, a company or a problem, the current state alone is rarely enough for me. I need to know what happened before. Which decisions were made, what followed from what, and how we got to the point where we are today.
I have looked at things this way for a long time.
While studying and using Event Sourcing, I gradually realized that this is exactly why the approach feels close to me. It preserves the events from which the state emerged and makes it possible to rebuild the state from them. [2]
It reminds me of the way I assemble my picture of the world from my own experience.
I don't take it as an explanation of how the brain works. For me it is a useful parallel — and it is interesting even in the places where it stops holding.
What does a system actually remember?
Let's imagine an ordinary order.
Today we can see that it has been paid, shipped and has a certain delivery address. For handling a routine query, that may be enough.
But behind this state there may be, for example, a history like this:
The order was created with address A.
The delivery address was changed to B.
The payment was received.
The order was shipped to address B.
Each record carries the data needed to describe the change. In Event Sourcing this history is not merely a supplement to the current row in a database. For the given part of the system it is the foundation from which we restore the state. [3]
So when the customer now asks why the parcel went somewhere other than usual, I have something to go back to.
I explain the situations around me in a similar way. I'm not interested only in the result. I need to understand the path.
Yet even here I must not mistake the record for the whole reality. A change of delivery address does not mean the customer has moved. Maybe they are just ordering a gift.
The event store is not a copy of reality. It is the system's memory of those events we decided to consider important.
Here I see a parallel with attention. I notice some things, I assign meaning to some, and some I don't capture at all.
In a system, we make this selection through the design of events. A domain event should capture a meaningful occurrence in the given domain, not necessarily the smallest technical movement. [4] Merely recording clicks or keystrokes does not yet mean that I reconstruct the application's state from those records — and therefore not that I am using Event Sourcing. [2]
For understanding how a form is operated, such telemetry can be useful. For reconstructing an order, however, I care primarily about which change was actually accepted. These two memories can exist side by side. They don't have to be one and the same thing.
I don't need to know all of tomorrow's questions today
What attracts me to Event Sourcing is the possibility of separating recorded facts from any particular view of them. On top of the stored events, different read models can be built depending on what we need to find out. [5]
With our order, today I care about the current state. Later I may ask how much time passed between receiving the payment and shipping. Or how many times customers changed the address before dispatch.
If I have preserved the necessary events and their data, I don't have to start collecting history only at the moment the question occurs to me.
This is where I see great value for business applications.
Demanding a complete list of future reports at the start of a project feels to me like an attempt to close the thinking before we have anything to think about. To me it is more natural to show a first view and let the next question arise over it.
"And what does it look like for orders where the address was changed?"
Such a question is not a failure of the original brief. It is a continuation of the search.
I don't have to decide today which views I will need. But I do have to decide which facts I want to preserve.
This boundary matters. If I didn't record the opening of a form, the history of completed orders won't tell me how many people abandoned it. A new view cannot create information I don't have.
So I am postponing the decision about interpretation, not the responsibility for data design.
When the error is in the view, not in the history
Another thing that fascinates me is the possibility of going back to the source material.
Imagine a report that incorrectly calculates order handling time from the moment the order was created, even though it should count from the moment the payment was received. The events are correct. The error lies in the way the result was derived from them.
I fix the calculation and rebuild the projection. I don't have to guess the past from a value once produced by a faulty algorithm. The preserved history makes recalculation possible. [3]
It reminds me of the moment when I look at an old experience with new understanding. I don't have to change the event in order to change my conclusion.
With a system, though, I need to distinguish two situations. An error in a calculation is one thing; incorrect information in the history itself is another. If we recorded a received payment incorrectly, replaying the same record won't solve the problem. I need a correction of the recorded facts, for example through a new corrective event. [6]
Likewise, fixing a projection must not charge the money again or ship the parcel again. Reconstruction of a view has to be separated from performing real operations. [2]
And over time, even the language in which we describe events may change. We must still be able to read the older formats — through versioning or conversion on load, without rewriting the stored history every time. [7]
What matters to me is to distinguish: fixing an error, a new analytical view, and a change of business rules. Recalculating the past with today's logic is not always the right answer. [2]
Events need context
When I try to understand a situation, it isn't enough for me to know that something happened before something else. I also care whether those things were related.
In a system, correlation identifiers help us with this. A correlation ID links the messages of one process; a causation ID points to the immediate message that caused the next one to come into being. They help reconstruct the chain of processing, not automatically reveal all of the customer's real motives. [8]
Time, too, is not a single value. A payment may take place in the morning, but the order system learns about it only in the afternoon. The question "when did it happen?" is different from "since when did we know about it?". [9]
This reminds me of situations where new information retroactively changes my understanding of an earlier decision.
In a distributed system, moreover, I cannot simply assume one shared ordering of all events. I have to determine where ordering matters and how I will ensure it. With asynchronous processing, individual views may also lag temporarily — that is part of what we call eventual consistency. [10]
In a company I picture it simply: one person already knows something has changed, another is still working with the original information. In an application, however, we need to design such a delay deliberately and present it to the user in an understandable way.
And sometimes we receive the same information twice. This is where idempotence comes in: processing the same event repeatedly must not cause a further change to the result. A payment notification delivered twice does not mean two payments. [3]
Memory has its price
Forgetting also belongs in this parallel for me.
I don't want to claim that people forget simply to save space. But research also shows cases where suppressing competing memories reduces their mutual interference during recall. Forgetting, then, need not be only a loss. [11]
For system design I take a question from this: What does it cost not only to store information, but also to keep it usable in the long run?
I'm not concerned only with disk capacity. I need to understand the data, protect it, be able to process it and know why I am keeping it at all.
That is why Event Sourcing does not mean "collect everything, it will come in handy someday" to me. It means deliberately deciding what the system should remember and for how long. When I remove part of the history, I also accept a limit on what I will later be able to learn from it. Depending on what I remove, I may even lose the ability to fully reconstruct the original state.
Besides the cost of retention, there is the cost of repeated recall.
When someone asks me where I work, I don't walk through my entire employment history in my head. I answer from my current picture.
In a system this reminds me of a snapshot: a stored state at a specific point in the stream. During reconstruction I load this state and add only the later events. A snapshot shortens the work, but on its own it does not replace the history. [12]
Forgetting a piece of information and not having to process it again every time are two different decisions.
What this leads to in an application
This is where the reflection returns to practical architecture for me.
With CQRS I can separate the model for changes from the models for reading. An order detail, a warehouse work overview and a management report don't have to use the same shape of data. Each view can be tailored to its purpose and, depending on the design, scaled independently. It is not, however, an automatic guarantee of higher performance. [5]
I'm also drawn to the image of individual histories that combine into a shared picture. It reminds me of people with their own experience and a team that builds a common understanding from their perspectives.
Technically, suitably partitioned event streams can be processed in parallel. But where they share dependencies, the need for coordination remains. Partitioning alone removes neither conflicts nor bottlenecks. [10]
That is why I would not derive a stream boundary automatically from the user. Two people can change the same order. What matters is which rules must remain valid together.
History also provides a basis for the capabilities that attract me to this architecture: explaining changes, returning to a previous view, or controlled reversal of operations. But "undo" does not have to mean returning the whole world to its original state. For a shipped parcel we need a follow-up process, not the erasure of the past. [13]
I could build autosave on this history as well. I still have to design what a work-in-progress change is, what gets stored and how I handle concurrent edits.
I approach auditing in a similar way. I want to be able to trace who made a change and what it followed from. Separately, however, I have to address things such as recording reads of sensitive data, denied access attempts or security incidents. A history of domain changes is not the same as a complete security audit.
To me these capabilities are not free features. They are features for which I have a shared and understandable foundation.
Why I keep coming back to this right now
AI also enters my thinking.
Tools today can help with implementation tasks and with designing tests. The mere availability of these capabilities, however, does not yet prove by how much they will make a particular project cheaper.
I see in them an opportunity to reduce the amount of repetitive work around projections, event processing and verifying different design variants.
That doesn't mean I stop needing to understand architecture. On the contrary: the easier something is to implement, the more important it is to know what should come into being and how I will recognize that it works correctly.
So what interests me is the possibility of devoting less effort to mechanical realization and more to understanding the domain. Not the notion that complexity has ceased to exist.
Where the comparison ends for me
I don't want a system to fill in a missing past by guessing. I want it to be able to distinguish a recorded event, a derived view, and information it does not have.
And even a rich history does not in itself mean understanding. A change of address tells me what the customer did. It doesn't have to tell me why.
Still, it is exactly this architecture that leads me to questions I consider important beyond software as well: What do we really know? What did our conclusion arise from? And can we go back to that source material?
What attracts me most about Event Sourcing is the possibility of not mistaking today's view for the only possible picture of what happened.
On my own, this is as far as I got with this reflection. To move further I need the experience of others.
Where does the parallel with human memory help you — and where, in your view, does it start to distort?
From understanding to internalizing
If you really want to internalize this way of thinking, go through the materials at the end of the article. Not as a list of definitions to memorize. Take a situation you know from your own work and first try to describe it through events instead of the resulting state.
What happened? What do you need to remember? What different views can you create from this history? And what, on the contrary, will you never learn from it?
To begin with, I would reach for the texts on Event Sourcing by Martin Fowler and Microsoft. [1] [2] [3] I would return to the other materials according to the questions you run into — not out of a need to cover all the concepts at once.
I'll be glad to guide you along this path — from a concrete problem through understanding the context to your own design and its verification in practice.
My aim is not to hand you yet another pattern. My aim is for you to build your own understanding and be able to recognize when this approach helps you and when it adds complexity needlessly.
If you would like to set out on this path together, get in touch. We can start right with the situation you are dealing with now.
Sources and further reading
The numbered references in the text lead to materials on the individual topics. The parallel between Event Sourcing and human memory is my own interpretation, not a conclusion of the technical sources listed, nor a claim that the brain works like an event store.
Sources verified on 19 September 2026. For continuously updated documentation, this refers to the version available on that date.
[1] Betts, Dominic; Domínguez, Julián; Melnik, Grigori; Simonazzi, Fernando; Subramanian, Mani. Exploring CQRS and Event Sourcing: A journey into high scalability, availability, and maintainability with Windows Azure. Microsoft patterns & practices, 2012; foreword by Greg Young. A freely available book (PDF and EPUB, approximately 380 pages) on the Microsoft Download Center. It follows a team with no prior CQRS experience from design through deployment to operating a sample system, and includes a reference section on CQRS and Event Sourcing as well as real-world case studies. Available for download as of 20 September 2026.
[2] Fowler, Martin. Event Sourcing. 12 December 2005. The basic principle, state reconstruction, replaying history, changes in processing and separating external effects during replay. The author labels the text as a work in progress.
[3] Microsoft. Event Sourcing pattern. Azure Architecture Center, Microsoft Learn. An overview of the design, idempotence, state reconstruction and the trade-offs of using this approach.
[4] Fowler, Martin. Domain Event. 12 December 2005. Capturing a meaningful occurrence in a domain and the difference between source information and its processing. The author labels the text as a work in progress.
[5] Microsoft. Command Query Responsibility Segregation (CQRS) pattern. Azure Architecture Center, Microsoft Learn. Separating models for changes and for reading, different projections, independent scaling and the related trade-offs.
[6] Fowler, Martin. Retroactive Event. 12 December 2005. Correcting the consequences of incorrect or late events and the limits of remedying operations already performed. The author labels the text as a work in progress.
[7] Axoniq. Event Versioning. Axon Framework Reference, version 5.3. Evolution of the event format and conversion of its representation during processing without having to rewrite stored data.
[8] Axoniq. Message Correlation. Axon Framework Reference, version 5.3. The meaning of correlation ID and causation ID when tracing how messages follow from one another.
[9] Fowler, Martin. Bitemporal History. 7 April 2021. Distinguishing the time a fact was valid from the time the system recorded it; working with information added retroactively.
[10] Microsoft. Event-driven architecture style. Azure Architecture Center, Microsoft Learn. Event ordering, asynchronous processing, eventual consistency, parallelism and the need for coordination.
[11] Wimber, Maria; Alink, Arjen; Charest, Ian; Kriegeskorte, Nikolaus; Anderson, Michael C. Retrieval induces adaptive forgetting of competing memories via cortical pattern suppression. Nature Neuroscience, 18, 582–589, 2015. DOI: 10.1038/nn.3973. A study on the suppression of competing memories during recall. It is not evidence that human memory works like a database or that forgetting simply saves storage capacity. The abstract is publicly available; the full text may require institutional access or a subscription.
[12] Axoniq. Snapshots. Axon Framework Reference, version 5.3. The snapshot as an optimization of state reconstruction, not a replacement for the event history.
[13] Microsoft. Compensating Transaction pattern. Azure Architecture Center, Microsoft Learn. Compensating operations already performed and the reasons why "undo" need not mean restoring the exact original state.
