Concepts
Event sourcing: state as a sequence of events
Intuition
Think of a bank statement: the balance tells you where you are now, but only the list of deposits and withdrawals shows how you got there. If someone discovers that an old entry was wrong, you can fix that entry and redo the math from it, instead of trying to guess the damage. Event sourcing records the entire history of changes, and the balance becomes something you can always recompute from it.
How it works
Event sourcing ensures that every change to application state is recorded as a sequence of events, and that all changes to domain objects are initiated by those events. Because the state can be derived from the log, it can be discarded and rebuilt by re-running the events on an empty application; a temporal query conceptually starts from a blank state and re-runs the events up to a certain moment or a certain event. In a replay, if a past event was incorrect, you reverse that event and the later ones and reapply the corrected one and the following ones, or you discard the state and replay the whole log with the correct event in place; the same technique works for events that arrived out of order. Rebuilding everything from scratch is slow when there are many events, so the current state can be cached, in memory or on disk, from snapshots: the system starts from an earlier snapshot and replays the events from there, and new snapshots can be taken in parallel without stopping the application. The official system of record can be the log (the databases are built from it) or the current state (and the events serve only for auditing and special processing). Reversing events is simpler when the event is a difference (add 10 to the account) than a final value (set the account to 110), which does not keep the previous value; it is also possible to go back to a past snapshot and replay. Since replays happen at will, external systems that cannot tell a replay from real processing are wrapped in a Gateway that knows when the processor is replaying, and in rebuilds and temporal queries it is usually enough to turn it off; external queries, such as the exchange rate on the day of the event, require historical data or a gateway that remembers the responses. New features and bug fixes to internal logic can be applied by reprocessing the events, but with external gateways you need to track the difference between what happened with the bug and without it, and rules that change over time need to go into the domain model itself, which can make the bitemporal behavior messy.
In practice
Fowler acknowledges that packaging every change as an event is not a natural choice, and that the technique is only worth it if there is a payoff. The payoffs he cites are the audit log, debugging (replaying real events in a test environment, stopping and going back as in a debugger), and the Parallel Models and Retroactive Events patterns, which require the technique; since it is very hard to retrofit Event Sourcing onto a system that was not born that way, Fowler recommends adopting it from the start if those patterns are likely. The author himself warns that the text is draft material from the mid-2000s.
Use it in a design
Practice the cases that rely on this concept in the System Design school.