Backend Transport
Event-Driven Architecture
Amazon processes millions of orders per day. When a buyer clicks Buy, dozens of processes fire: payment verification, warehouse reservation, seller notification, delivery calculation. How does this work without a single monolithic service coordinating everything? Through events - each system reacts to facts rather than waiting for commands.
- **Netflix** publishes viewing events to Kafka. Recommendation, analytics, and anti-fraud services subscribe independently - each processes at its own pace without coupling.
- **Uber** built the entire Trip lifecycle on events: DriverMatched, RideStarted, RideCompleted. 100+ services subscribe and react autonomously.
- **Stripe** stores all transactions as immutable events. This allows historical scenarios to be replayed, every change to be audited, and state to be rolled back to any point in time.
Events vs Commands
A Command is an intention: "CreateOrder", "CancelPayment". An Event is a fact that occurred in the past: "OrderCreated", "PaymentCancelled". The difference is fundamental: a command can be rejected, an event cannot. Commands are addressed to a specific recipient; events are broadcast to anyone who wants to listen.
Amazon and Netflix build architectures on events: a service publishes what happened without knowing who is listening. This gives loose coupling - adding a new consumer requires no changes to the publisher.
What is the fundamental difference between an Event and a Command in event-driven architecture?
Event Sourcing
Event Sourcing is a pattern for storing state as a sequence of events instead of a current snapshot. Current state = replay of all events from the beginning. This provides a complete change history, the ability to time-travel, and audit by default.
An Event Store keeps events in an append-only log. For long histories, snapshots are used: save the current state at version 1000, then replay only from version 1001. Kafka with retention=forever becomes an event store.
How is the current state of an object obtained in an Event Sourcing system?
CQRS: Separating Reads and Writes
CQRS (Command Query Responsibility Segregation) separates write operations (Commands) and read operations (Queries) into different models. The write side is optimized for business logic and consistency; the read side is optimized for specific UI queries.
CQRS without Event Sourcing is possible: simply different models for reads and writes in the same DB. Event Sourcing without CQRS is also possible. They are often combined, but it is not mandatory.
What core problem does CQRS solve?
Eventual Consistency
In distributed systems, strong consistency requires coordination across nodes - this is slow and limits availability (CAP theorem). Eventual Consistency: the system guarantees that, in the absence of new writes, all nodes will eventually reach the same state.
Amazon S3 provides strong consistency for objects since 2020 - previously it was eventual. DynamoDB offers both modes. DNS is a classic example of eventual consistency: a record change propagates to all servers over hours.
A system with eventual consistency shows a stale balance for 200 ms after a deposit. This is:
Event Storming
Event Storming is a workshop technique for collaboratively modeling business domains through events, introduced by Alberto Brandolini. All participants (developers + business) put sticky notes on a wall: orange for events, blue for commands, yellow for aggregates.
Event Storming takes 4-8 hours for a complex domain. The result is an event map that reveals bounded contexts (microservice boundaries) and critical business processes. Used at Airbnb, ING Bank, and Pivotal.
Event-Driven Architecture and Event Sourcing are the same thing
EDA is an architectural style for communication through events. Event Sourcing is a pattern for storing state. One can use EDA without Event Sourcing and vice versa.
EDA describes how services interact (through events instead of direct calls). Event Sourcing describes how to store state inside a service (event log instead of a current snapshot). These are orthogonal concepts.
What is the main outcome of an Event Storming session?
Key Ideas
- **Events vs Commands** - an event is a fact (cannot be rejected), a command is an intention (can be rejected). Event-driven architecture is built on facts.
- **Event Sourcing** - state as an event log; current state = replay. Provides audit, history, and the ability to build new projections from old data.
- **CQRS + Eventual Consistency** - the write model is optimized for consistency, the read model for UI queries. Replication lag is a deliberate trade-off.
Related Topics
Event-Driven Architecture relies on message brokers and gives rise to reliability patterns:
- Kafka as Event Log — Kafka is a natural event store for EDA: append-only, retention forever, replay from any point
- Saga Pattern — Sagas are an EDA pattern for distributed transactions: a sequence of events and compensations instead of 2PC
Вопросы для размышления
- In which cases is eventual consistency unacceptable and strong consistency is required? How does that affect architecture?
- What happens in an Event Sourcing system when the schema of an event needs to change from v1 to v2, but old events are already recorded?
- How does Event Storming help identify microservice boundaries (bounded contexts) better than analyzing existing code?