TracksSpecializations and Deep DivesServerless and Event-Driven SystemsEvent-Driven Architecture Patterns(4 of 7)

Event-Driven Architecture Patterns

Event-driven architecture uses events as the primary way systems communicate. Instead of services calling each other directly, they publish events that other services react to. This decoupling enables systems that scale better and fail more gracefully.

Event Notification

The simplest pattern: when something happens, publish an event. Interested services subscribe and react:

Order Service publishes: "OrderCreated"

Inventory Service: reserves items
Email Service: sends confirmation
Analytics Service: records the sale

Each service operates independently. If the email service is down, orders still process. The email sends when the service recovers.

Event Sourcing

Instead of storing current state, store the events that led to that state:

Traditional: User { balance: 150 }

Event Sourced:
  AccountOpened { initial: 100 }
  Deposited { amount: 100 }
  Withdrawn { amount: 50 }
  → Current balance: 150

You can rebuild current state by replaying events. You get a complete audit trail. You can ask "what was the balance last Tuesday?" by replaying events up to that point.

Event sourcing is powerful but adds complexity. Use it when audit trails matter or when you need to understand how state evolved.

CQRS: Command Query Responsibility Segregation

Separate your read and write models:

Commands (writes) → Write Model → Events → Read Model ← Queries (reads)

The write model is optimized for consistency and business rules. The read model is optimized for query performance — maybe denormalized, maybe in a different database entirely.

This lets you scale reads and writes independently and optimize each for its purpose.

The Saga Pattern

Distributed transactions across services are hard. Sagas break them into steps, each publishing an event for the next:

1. Order Service: CreateOrder → publishes OrderCreated
2. Payment Service: ProcessPayment → publishes PaymentCompleted
3. Inventory Service: ReserveItems → publishes ItemsReserved
4. Shipping Service: ScheduleShipment → publishes ShipmentScheduled

If step 3 fails, compensation events undo previous steps: RefundPayment, CancelOrder. It's eventual consistency rather than immediate, but it works across service boundaries.

Handling Failures

Events can fail to process. Design for this:

  • Idempotency: Processing the same event twice should be safe
  • Dead letter queues: Failed events go somewhere for investigation
  • Retry policies: Automatic retries with backoff

See More

Further Reading

You need to be signed in to leave a comment and join the discussion