CONCEPT Cited by 1 source
Competing sources of truth (event stream)¶
Definition¶
Competing sources of truth is the anti-pattern where multiple independent systems each claim to hold the authoritative version of a domain entity (product, order, customer), typically because every consumer built its own local store from a shared event stream and transformed the data along the way. Each hop applies its own massaging — field renames, filtering, flattening, derived attributes — so by the time a downstream consumer reads the data, it has been through multiple rounds of silent translation and no longer matches what the producer emitted.
Zalando's PRAPI write-up names this directly:
"Teams with engineering capacity consumed events, modified data to fit their needs, and exposed their own APIs or event streams. Those without the capacity relied on an existing unified data source, such as our Presentation API, inheriting its version of product data. This led to competing sources of truth."
"A good analogy is the children's whispering game— product data was altered at each step, and by the end, it no longer resembled the original. With no data lineage, there was no way to trace attributes back to their intended meaning."
(Source: sources/2025-03-06-zalando-from-event-driven-chaos-to-a-blazingly-fast-serving-api.)
Why event-stream-only architectures produce this¶
- Every team owns their own store. The architectural default "subscribe to the stream, replay from the dawn of time, build your local model" pushes the responsibility for data shape onto the consumer. Each consumer optimises for their query patterns; their representation drifts from the producer's.
- No canonical read path. Without an authoritative API, there's no unambiguous place for a new consumer to ask "what does this entity look like?" — they pick whichever store their mentoring team uses. That store is probably already 2–3 hops downstream of the producer.
- No data lineage. Events don't carry their transformation history; a downstream store has no structural way to recover the original producer-emitted form.
- Transform-on-consume amplifies drift. Each consumer's transform is independently maintained; over time they diverge from each other and from the producer.
The API-based fix¶
The fix is not to abandon event-driven architecture — the producer side usually keeps its event streams. The fix is to provide a canonical read API that is authoritative and performant enough that consumers stop rebuilding local stores. Once calling the API is faster and simpler than maintaining a local copy, the competing-sources problem naturally resolves:
- Consumers that need the canonical form call the API.
- Teams that still need bespoke representations can project from the API instead of re-deriving from events.
- The API owner can track usage and sunset legacy formats
via content negotiation (
Acceptheaders).
Zalando's execution is explicit: PRAPI assumed ownership of
all four legacy representations (alpha, beta, gamma,
new standard application/json) and emitted the legacy
formats back onto event streams during the sunset period
so legacy producers could decommission immediately while
consumers migrated on their own schedule. See
patterns/api-as-single-source-of-truth-over-event-streams
and
patterns/accept-header-format-negotiation-for-legacy-sunset.
Related anti-patterns¶
- Distributed monolith via shared events — the event stream becomes a contract between every team, changing the schema requires coordinating N teams.
- N-hop data derivations — the further a consumer is from the producer, the more stale and massaged its copy.
- Per-team materialised view explosion — one entity, dozens of locally-maintained projections, none of them owning the canonical shape.
Seen in¶
- sources/2025-03-06-zalando-from-event-driven-chaos-to-a-blazingly-fast-serving-api — canonical Zalando write-up of the pathology and its API-over-stream fix (PRAPI + PODS).
Related¶
- concepts/canonical-data-model — the fix frame
- concepts/data-lineage — what was missing
- concepts/event-driven-architecture — the substrate (not the enemy)
- concepts/cqrs — the organising principle for producer (command) vs. consumer (query) split
- patterns/api-as-single-source-of-truth-over-event-streams
- systems/zalando-prapi