Read Model
A data model optimized for queries, built from events in a CQRS architecture.
A read model (also called a projection) is a data model optimized for reading.
It can be simply a dedicated SQL query to get a specific view of the data. It could also be a separate storage system (like a NoSQL database, search index, or in-memory cache) that is updated asynchronously from the write side.
In event-driven architectures, read models are often built and updated by processing events from the write side. The write side stores data in a normalized form optimized for consistency and writes. The read model transforms this data into a format that is fast to query for specific use cases.
For example, a booking system might store bookings as normalized rows in PostgreSQL (write side), but maintain a denormalized view with pre-joined customer and venue data for the booking list page (read model).
On an Event Storming board, read models are the green sticky notes: what users see on a screen, or data a command reads before deciding what to do.
Read models can be rebuilt from scratch by replaying events. This makes them disposable and replaceable: if you need a new view of your data, you create a new read model and populate it from the event history.
References
- How to use basic CQRS in Go — Explains how to define read model interfaces for queries and how read models can use different storage backends. Discusses the progression from querying write models to polyglot persistence with separate read model stores.
- Common Anti-Patterns in Go Web Applications — Explains why the views your API returns (read models) are not the same thing you store in the database (write models), and why separating these concerns avoids common anti-patterns.
- When using Microservices or Modular Monolith in Go can be just a detail? — Mentions read models as a responsibility of the application layer in Clean Architecture, where it provides views for querying data.
- The Repository pattern in Go: a painless way to simplify your service logic — Notes that repository update functions can return read models alongside other results like event sourcing events.
- Synchronous vs Asynchronous Architecture — Discusses how message ordering affects read models built from events. If events arrive out of order, read models may end up in an incorrect state.
- Event-Driven Architecture: The Hard Parts — Covers how event ordering and poison queues impact read models. If events like addUser and removeUser arrive out of order, read models may become inconsistent.