← Week 3: Event Sourcing & CQRS

Day 19: Event-Driven Architecture

Phase 4 · Aug 9, 2026

← Week 3: Event Sourcing & CQRS

Agenda (2–3 hours)

  • Read (45 min): Amazon "Event-Driven Architecture" whitepaper; Martin Fowler "What do you mean by Event-Driven?" blog post
  • Study (45 min): Distinguish between event notification, event-carried state transfer, and event sourcing — when does each apply?
  • Practice (45 min): Design an event-driven order fulfillment flow using SQS + SNS; draw the event flow from order placed to shipped
  • Challenge (30 min): How do you handle long-running business processes (multiple events over days) in an event-driven system? What is the "process manager" pattern?
← Week 3: Event Sourcing & CQRS

Three Patterns of Event Usage

Event Notification: "something happened; consumers can react"

  • Publisher doesn't know or care who listens
  • Payload is minimal (just what changed)
  • Decoupled; asynchronous

Event-Carried State Transfer: "here is the full state of the thing that changed"

  • Consumers don't need to call back to get more data
  • Larger payload; snapshot of entity at time of event

Event Sourcing: "this event is the authoritative record; state is derived from it"

  • Events are never deleted; log is the source of truth
  • Enables replay, temporal queries, new projections
← Week 3: Event Sourcing & CQRS

Dead Letter Queues

Events that can't be processed go to a Dead Letter Queue (DLQ):

SQS queue → consumer fails 3 times → message moved to DLQ
DLQ → alerting (CloudWatch alarm) → human investigation
// SQS DLQ configuration
let queue = sqs.create_queue()
    .attributes(QueueAttributeName::RedrivePolicy, json!({
        "maxReceiveCount": "3",
        "deadLetterTargetArn": dlq_arn
    }).to_string())
    .send().await?;

Without DLQ: failed messages block the queue indefinitely (or are silently dropped). Always configure DLQs in production.

← Week 3: Event Sourcing & CQRS

Process Manager Pattern

For long-running workflows that span multiple events and time periods:

struct OrderFulfillmentProcess {
    order_id: Uuid,
    state: FulfillmentState,
    started_at: DateTime<Utc>,
}

enum FulfillmentState {
    WaitingForPayment,
    WaitingForInventory,
    WaitingForShipment,
    Completed,
    Failed(String),
}

The process manager listens to events, correlates them by order ID, and drives the workflow to completion. It's the orchestrator in a choreography-heavy system.

AWS Step Functions is a managed process manager.

← Week 3: Event Sourcing & CQRS

Saga vs Process Manager

Pattern State storage Duration Complexity
Saga Explicit state machine Short (seconds to minutes) Medium
Process Manager Event log + correlation Days to weeks Higher
Step Functions Managed Seconds to years Low (managed)

Sagas are for transactional workflows. Process managers are for long-running business flows that span multiple asynchronous events over time.

← Week 3: Event Sourcing & CQRS

Key Takeaways

  • Event notification vs state transfer vs event sourcing: different patterns for different needs
  • Always configure DLQs on consumer queues; alert on DLQ depth
  • Process managers (or Step Functions) manage long-running workflows that span multiple events
  • Dead-letter queues + process managers together handle the full reliability spectrum

Tomorrow: Kafka fundamentals — high-throughput event streaming.