Across services you usually trade strong consistency for eventual consistency, and lean on CQRS and event sourcing to make that practical and correct.
Eventual consistency
After a change, replicas converge "soon" rather than instantly. Acceptable for most business flows (an inventory count can lag a second), unacceptable for some (a bank balance check).
CQRS (Command Query Responsibility Segregation)
Separate the write model from one or more read models.
Command ─▶ Write model ─emits events─▶ [ Read model(s) ]
Query ──────────────────────────────▶ Read model (denormalized, fast)
Reads scale and reshape independently of writes; the read model is updated from events, so it's eventually consistent.
Event sourcing
Store the sequence of events as the source of truth, not just current state. Current state is a fold over events.
AccountOpened ─▶ Deposited(100) ─▶ Withdrew(30) ─▶ state: balance = 70
(events are immutable + append-only → full audit + time travel)
Trade-offs
| Technique | Gains | Costs |
|---|---|---|
| Eventual consistency | Availability, scale | Stale reads, conflicts |
| CQRS | Read/write scale | Two models to keep in sync |
| Event sourcing | Audit, replay, history | Schema/event evolution, complexity |
Pitfall
Don't adopt event sourcing everywhere — it's powerful but heavy. Use it where audit/history truly matters.
Why it matters
Distributed systems can't have strong consistency, availability, and partition tolerance all at once, so senior design is about choosing where eventual consistency is acceptable.
CQRS and event sourcing give you the tools to make eventual consistency reliable and auditable — but each adds real complexity, so apply them surgically, not by default.
