Go architectures · 3 MIN READ
Event sourcing: state from a durable history
Distinguish a source of truth from ordinary logs and notifications.
Distinguish a source of truth from ordinary logs and notifications. An event-sourced aggregate reconstructs state from accepted domain events. Trace the worked Go example, then compare the benefit with the cost before applying this design to your own project.
Architecture · A MAP OF THE IDEA
- Validate command against current state
- Append events at an expected version
- Replay events into state
Useful when
- Temporal reconstruction is a product requirement
- Domain history must be explicit
Watch out
- Replay and schema evolution need long-term support
- External side effects need separate deduplication
Implementation & operation cost: Very high
Fit depends on the task
Editorial suitability, not benchmarks or a universal ranking. Styles describe different axes and can be combined.
The design decision
An event-sourced aggregate reconstructs state from accepted domain events. The event stream is authoritative, so event meaning and ordering must remain interpretable for years. This differs from logging what a conventional database already stored.
A complete Go example
Read this program from the entry point and follow the calls shown in the diagram. The output is included at the end so you can check the behavior without a compiler.
package main
import (
"fmt"
)
type Event struct{ Delta int }
func replay(events []Event) int {
balance := 0
for _, e := range events {
balance += e.Delta
}
return balance
}
func main() {
events := []Event{{Delta: 50}, {Delta: -20}}
fmt.Println(replay(events))
fmt.Println(replay(events[:1]))
}
// Output:
// 30
// 50
Replaying both events yields 30; replaying the prefix yields 50. The slice only demonstrates deterministic reduction. A real event store also needs append version checks, durable writes, event schemas and a policy for replaying external side effects.
Tradeoffs and the simpler alternative
Choose this when temporal history and reconstruction are core requirements. Replay must not resend emails or charge cards. Event evolution, privacy deletion and projection rebuilds are significant costs; an audit table is often enough for a conventional service.
Treat event history as a durable contract
An event records a business fact such as OrderAccepted, with identity, aggregate sequence and event schema version. Replaying history applies facts without sending emails or charging cards again. Validate a command against the current aggregate state, decide new events, then append with an expected stream version. A read-then-append sequence without concurrency control can accept conflicting commands. Event sourcing stores state transitions as the source of truth; a message broker alone is not that event store.
Plan evolution, snapshots and sensitive data
An old event cannot silently change meaning when a struct is renamed. Use version-aware decoders or explicit upcasting and retain replay fixtures from historical versions. A snapshot is a performance aid tied to a known event sequence, not a replacement for missing history. Avoid embedding secrets and unnecessary personal data in immutable events; deletion and retention obligations need a deliberate design. Do not describe immutable storage as automatically satisfying every audit requirement.
Separate replay from external side effects
An event handler updating a projection can be replayed; an external payment requires a durable idempotency key and side-effect policy. Test rebuilding an empty projection from the whole stream and compare state with incremental processing. Test conflicting expected versions and malformed historical events. Adopt event sourcing when historical reconstruction and domain behavior justify its substantial operational cost. An append-only audit log beside ordinary state may solve a simpler audit requirement more cheaply.
TAKE THIS WITH YOU
Rebuilds authoritative state from accepted events. Choose this when temporal history and reconstruction are core requirements. Replay must not resend emails or charge cards. Event evolution, privacy deletion and projection rebuilds are significant costs; an audit table is often enough for a conventional service.
Check your understanding
Which statement best describes Event sourcing: state from a durable history?
Go to the source
Progress stays in this browser. No account needed.