Skip to main content

CQRS and Event Sourcing on Cloud

A GCP microservices design separating write and read models with event sourcing on Cloud Spanner, Pub/Sub, Firestore, and BigQuery for full auditability and independent scaling. It is powerful but complex, and overkill for simple CRUD.

Cloud Provider
GCP
Components
6
Use Cases
3
Standards
4

Overview

This architecture applies Command Query Responsibility Segregation (CQRS) with event sourcing on managed GCP services. CQRS separates the write side (commands that change state) from the read side (optimized queries), and event sourcing records every state change as an immutable event rather than overwriting current state. Use it when you need a complete audit trail, complex domains with very different read and write loads, or the ability to rebuild and reshape read models at will.

The event log becomes the system of record, and read models are projections derived from it.

Components

  • Cloud Run: Hosts stateless command and query services that scale independently.
  • Pub/Sub: Carries domain events from the write side to projection builders.
  • Cloud Spanner: Strongly consistent store for the event log and command-side state.
  • Firestore: Low-latency read models for application queries.
  • BigQuery: Analytical read model for reporting over the full event history.
  • Cloud Monitoring and Trace: Observability across commands, events, and projections.

Data Flow

A command request reaches a write service on Cloud Run, which validates it and appends one or more immutable events to the event log in Cloud Spanner. Each committed event is published to Pub/Sub. Projection services consume events and build read models: one writes denormalized documents to Firestore for fast application reads, another streams events into BigQuery for analytics. Query services read exclusively from these projections, never from the write store. Because every event is retained, new read models can be built by replaying history.

Scaling and Resilience

Write and read sides scale independently on Cloud Run, matching capacity to each workload's very different demands. Pub/Sub buffers events and retries delivery, decoupling projection speed from command throughput. Read models can be rebuilt by replaying the event log, which also serves as recovery after a projection bug. Idempotent projection handlers tolerate redelivery, and dead-letter topics capture poison events. Spanner provides horizontal scale with strong consistency for the authoritative log.

Security

Services run as least-privilege service accounts, and only command services may write to the event log. Events carry no more data than necessary, and sensitive fields are encrypted or tokenized. Pub/Sub topics are access-controlled, and data is encrypted at rest and in transit. The immutable event log itself is a strong audit and compliance asset. VPC Service Controls can wrap data services to prevent exfiltration.

Trade-offs and Alternatives

CQRS with event sourcing delivers auditability, independent scaling, and flexible read models, but it is significantly more complex: read models are eventually consistent, event-schema evolution requires discipline (versioning and upcasting), and replaying large logs takes planning. The pattern is overkill for simple CRUD applications, where a single relational model is far cheaper and clearer. Apply CQRS selectively to the bounded contexts that truly benefit, not the whole system. Choose this architecture when audit requirements, asymmetric read/write loads, or domain complexity justify the cost.