I started the year using Gemini Pro to take our integration patterns and covert them into “playing card” style pattern library so that we can print and play! The content is mine, I used AI to generate the images with still a few issues with image text – oh well, maybe something to refine later in 2026 or next year. In this post we explore “Read-side” or Query based integration patterns where performance and correctness are key design decisions. These patterns separate “freshness” from “availability” by design and lean heavily on C.A.P theorem
Included patterns
- QP-1 — Real-time Consistent Read (Master)
- QP-2 — Real-time Cached Read (Operational Data Store)
- QP-3 — Real-time Cached Bulk Read
QP-1: Real-time Consistent Read (Master)

Synchronous read that returns the latest committed state from the system-of-record (master).
When to use
- Client requires latest state (strong consistency).
- Throughput is low to moderate and latency can be higher.
- Fine-grained reads (by ID, small payloads).
Pros
- Always freshest data.
- Simple client semantics (no staleness handling).
Cons
- Lower availability under partitions; can be slower.
- Can overload master if used for high-volume read traffic.
PlantUML
@startuml
title Real-time Consistent Read (Master)
actor "Client" as Client
participant "API/BFF" as API_BFF
participant "Master System" as Master_System
Client -> API_BFF: GET /resource/{id}
API_BFF -> Master_System: Read latest state
Master_System -> API_BFF: 200 OK (fresh data)
API_BFF -> Client: 200 OK (fresh data)
@enduml
QP-2: Real-time Cached Read (Operational Data Store)

Synchronous read served from an operational cache/ODS refreshed from master.
When to use
- Client can tolerate slightly stale data (bounded staleness).
- High read throughput and low latency are required.
- Fine-grained reads.
Pros
- High throughput and low latency.
- Protects the master from read load.
- Improves availability.
Cons
- Stale reads possible.
- Cache invalidation/refresh complexity.
- Requires cache warm-up and consistency monitoring.
PlantUML
@startuml
title Real-time Cached Read (Operational Data Store)
actor "Client" as Client
participant "API/BFF" as API_BFF
participant "Cache/ODS" as Cache_ODS
participant "Master System" as Master_System
Client -> API_BFF: GET /resource/{id}
API_BFF -> Cache_ODS: Lookup cached state
Cache_ODS -> API_BFF: 200 OK (cached state)
API_BFF -> Client: 200 OK (cached state)
@enduml
QP-3: Real-time Cached Bulk Read

Synchronous read for large subsets using indexed cache/ODS to serve bulk queries quickly.
When to use
- Client needs a large subset (search/filters) with low latency.
- Master cannot support complex/high-volume bulk queries.
- Staleness is acceptable.
Pros
- Fast bulk queries.
- Offloads master query complexity.
- Enables richer query models (search/index).
Cons
- Staleness and sync lag.
- Index/ODS build and operational overhead.
- Risk of cache used as primary source unintentionally.
PlantUML
@startuml
title Real-time Cached Bulk Read
actor "Client" as Client
participant "API/BFF" as API_BFF
participant "Search Index/ODS" as Search_Index_ODS
participant "Master System" as Master_System
Client -> API_BFF: GET /resources?filter=...
API_BFF -> Search_Index_ODS: Query indexed dataset
Search_Index_ODS -> API_BFF: 200 OK (result set)
API_BFF -> Client: 200 OK (result set)
@enduml
Summary
We looked at simple query patterns which can be composed into more complex end to end solutions for back and forth query chains. Before implementing though we must consider the following:
- Define the contract first (schema, idempotency key, ordering expectations)
- Make retries safe (idempotent handlers, dedupe, at-least-once assumptions)
- Prefer explicit staleness windows over implicit “eventual consistency” depending on usecase and business needs
- Instrument job state and failure modes (metrics + searchable logs) because operability is a key ility!
Let me know your most used pattern – do you keep it simple generally? What is the most complex read/query ask and why?
Also, how would we use simple query patterns to get a large body of data or large collection iteratively? Tell me your answer