Martin Fowler’s presentation on Event-Driven Architecture (EDA) highlights the varied interpretations of “event-driven” and categorizes them into four distinct patterns to provide more precision in software development discussions. He begins by noting that while the term “event-driven” is commonly used, its specific meaning often varies, leading to confusion. To address this, a workshop was held to identify and define common patterns, resulting in the four patterns discussed in the talk.

1. Event Notification

This is the most common pattern.

  • Systems use events to notify other systems about a change.
  • The source system does not need to know what downstream systems will do with the event.

Example

  • Event: “Customer address changed”

Benefits

  • Decouples systems.
  • New consumers can subscribe to events without modifying the producer.
  • Enables flexibility and easier integration.

Event vs Command

  • Event
    • States that something already happened.
    • Example: “Customer address changed”
  • Command
    • Requests something to happen.
    • Example: “Re-quote insurance for this customer”

Drawback

  • Harder to understand the overall system flow.
  • There is no central code controlling what happens after an event.
  • Debugging requires tracing message flows, similar to debugging a complex GUI event system.

2. Event-Carried State Transfer

This pattern extends Event Notification. Instead of only notifying that something changed, the event includes the actual data (state).

Example

Instead of:

CustomerAddressChanged

The event carries:

CustomerAddressChanged
{
  customerId
  newAddress
}

Key Idea

  • Events contain both the notification and the data.

Benefits

  • Downstream systems can keep a local copy of required data.
  • Reduces or eliminates direct API calls to the source system.
  • Improves:
    • Performance
    • Availability
    • Scalability

Advantages

  • Fewer remote calls
  • Less load on source system
  • Systems can function even if the source system is temporarily unavailable

Trade-offs

  • Eventual consistency
    • Data across systems may not be immediately synchronized.
  • Data duplication
  • More complexity in maintaining consistency over time

3. Event Sourcing

Event Sourcing changes how application state is stored. Instead of storing the current state, the system stores a sequence of events representing every change. The current state can be reconstructed by replaying these events.

Conceptual Comparisons

  • Git
    • Current codebase is derived from a sequence of commits.
  • Accounting ledgers
    • Balance is calculated from credits and debits.

Advantages

  • Complete audit trail
    • Every change is recorded.
  • Powerful debugging
    • Replay events to understand how a state was reached.
  • Time travel
    • View application state at any moment in the past.
  • Memory image systems
    • Event log becomes the permanent storage.
    • Application state can stay entirely in memory for performance.
    • Used in systems like LMAX.

Challenges

  • Unfamiliar mental model
    • Developers must think differently about persistence.
  • External system interactions
    • Responses from external systems must also be recorded as events to allow replay.
  • Event schema versioning
    • Event structures evolve over time.
    • Older events must still work with newer code.
  • Asynchronous processing
    • Not mandatory, but often used, which adds complexity. Greg Young - Event Sourcing

4. CQRS (Command Query Responsibility Segregation)

CQRS separates read operations and write operations into different models.

Core Idea

  • Commands → Modify data
  • Queries → Read data Each side uses different models, and sometimes different databases.

Command Model

  • Handles business logic
  • Focused on data modification

Query Model

  • Optimized for efficient data retrieval
  • Designed specifically for reading operations

Key Rule (Greg Young’s definition)

  • The command model is never used for reading.
  • All reads must go through the query model. Even reads needed during command processing should use the query side.

Benefit

This strict separation allows:

  • Independent optimization of write logic
  • Independent optimization of read performance

Conclusion

Martin Fowler emphasizes that understanding these four patterns provides a more precise vocabulary when discussing event-driven systems. The four patterns are:

  • Event Notification
  • Event-Carried State Transfer
  • Event Sourcing
  • CQRS Using these distinctions helps developers:
  • Identify appropriate architectural techniques
  • Anticipate potential challenges
  • Make more informed design decisions This precision is similar to how the term “microservices” offers a clearer definition within the broader concept of service-oriented architecture.