Skip to main content

CQRS with Event Sourcing

State is derived from an append-only event log, with CQRS separating command handling from projected read models. The design delivers full auditability and independently scalable reads and writes on Azure serverless services.

Cloud Provider
AZURE
Components
7
Use Cases
3
Standards
5

Overview

Some domains need a complete, immutable history of what happened: ledgers, order systems, regulated workflows. Event sourcing stores every state change as an append-only event, making the log the source of truth. CQRS (Command Query Responsibility Segregation) splits the write side, which validates commands and appends events, from the read side, which serves queries from purpose-built projections. Together they give auditability, temporal queries, and independently scalable reads and writes.

Use this when an audit trail is mandatory, when reads and writes have very different scaling profiles, or when you need to reconstruct past state.

Components

  • API Management: the public API surface, applying authentication, rate limits, and routing.
  • Azure Functions: command handlers that validate and append events, and projection handlers that build read models.
  • Cosmos DB: the append-only event store, partitioned by aggregate.
  • Event Hubs: streams committed events to projection and integration consumers.
  • Azure SQL: holds relational read models for rich queries.
  • Redis: caches hot read models for low-latency lookups.
  • Application Insights: traces commands end to end and monitors projection lag.

Data Flow

A command arrives through API Management to a command-handler function, which loads the aggregate's events, validates the command, and appends new events to Cosmos DB. Each commit emits to Event Hubs. Projection functions consume the stream and update Azure SQL and Redis read models. Queries hit the read side directly, never touching the write path.

Scaling and Resilience

The write side scales by aggregate partition; the read side scales independently by query load. Because the event log is the source of truth, read models can be rebuilt or added at any time by replaying events. Idempotency keys on commands and dedup on projections handle retries safely. Sagas coordinate multi-aggregate workflows with compensating events when steps fail.

Security

API Management enforces OAuth and rate limiting at the edge. Functions use managed identities with least-privilege access to Cosmos DB and SQL. The event store is append-only and immutable, providing a tamper-evident audit trail. Sensitive event payloads are encrypted, and projections expose only the fields each consumer needs.

Trade-offs and Alternatives

Event sourcing is conceptually demanding: eventual consistency between write and read sides, schema evolution of historical events, and projection rebuilds all require discipline. For simple CRUD, a single relational database is far simpler. Adopt CQRS without event sourcing when you need read/write scaling but not full history. Reserve the full pattern for domains where auditability and temporal reconstruction justify the cost.