Integration Patterns

Eventual Consistency

Accept brief, expected divergence between systems and design so it does no harm.

What you'll learn

  • Define eventual consistency in plain terms
  • Recognise where it appears in integrations
  • Design reads that tolerate slightly stale data
  • Avoid assumptions that require strict consistency
  • Communicate consistency expectations to users

6 min

What it means

Eventual consistency is the guarantee that, if updates stop, all copies of data will eventually agree — but for a short window they may not. After a write, a read might briefly return the old value before the change propagates.

This is not a defect; it is a deliberate trade in distributed systems. Strict consistency — every read always reflecting the latest write everywhere — is expensive and limits availability and scale. Many systems instead accept a brief lag in exchange for being faster and more resilient. Understanding this stops you writing integration code that assumes an update is visible everywhere the instant it succeeds, which is often simply untrue.

Where you meet it

Eventual consistency shows up across integrations, often surprisingly. A few common encounters:

  • Read-after-write — you create something, immediately read it back, and it is not there yet.
  • Replication lag — a read replica trails the primary by a moment.
  • Propagated updates — a change takes time to ripple through caches and downstream systems.
  • Event delivery — notifications arrive slightly after the change they describe.

The unifying theme is a gap between a change succeeding and that change being visible everywhere. Code that ignores this gap works in testing and fails intermittently in production, which is the hardest kind of bug to chase.

Designing for it

The remedy is to make your logic tolerant of brief staleness rather than to demand instant consistency. Several habits help.

Do not assume a just-written value is immediately readable elsewhere; if you need it, keep it from the write rather than re-fetching. Make reads idempotent and safe to repeat, so a retry that hits stale data is harmless. Where freshness genuinely matters, poll until the expected state appears rather than failing on the first stale read. Above all, avoid read-after-write assumptions in flows that span systems. Designing for staleness up front turns a class of flaky, intermittent bugs into behaviour you have already accounted for.

Setting expectations

Consistency is also a communication issue. If users might see a change before it is fully reflected, say so plainly — a small updating… indicator beats a confusing apparent error. Managed expectations turn a quirk into a non-issue.

// poll until the expected state appears
while not record.is_visible() and within_deadline():
    wait()
    record = fetch()

The same applies between systems: document which data is eventually consistent so consumers do not build brittle assumptions on top of it. Eventual consistency handled openly is a reasonable trade; handled silently it becomes a steady source of confusion and support load. See synchronisation patterns for how reconciliation closes the gap.

Key takeaways

  • Eventual consistency means copies agree in time, not instantly
  • It is a deliberate trade for availability and scale, not a bug
  • It appears in read-after-write, replica lag and propagated updates
  • Design reads to tolerate brief staleness and avoid read-after-write assumptions
  • Communicate consistency expectations to users and downstream consumers

FAQ

Is eventual consistency a bug?

No. It is a deliberate design trade in distributed systems: accepting a brief window where copies disagree in exchange for greater availability and scale. The guarantee is that they converge once updates stop.

Why might a record I just created not appear?

Because the write may not yet be visible to the replica or cache your read hit. This read-after-write lag is normal under eventual consistency; poll until it appears, or keep the value from the write itself.

How do I design around it?

Avoid assuming a just-written value is instantly readable everywhere, make reads safe to repeat, poll for the expected state where freshness matters, and communicate the lag to users rather than presenting it as an error.

Integrate with Merion

Ready to build?

Read the API reference, grab the OpenAPI spec, and ship a resilient integration.