What actually fails in a two-way sync

A one-way integration has one difficult question: which fields move, and in what shape. A two-way integration has a second and much harder one: when the same record has changed on both sides since the last synchronisation, which version is correct? Most implementations never answer it explicitly. They simply apply whichever update arrives last, which means the outcome depends on network timing rather than on business rules.

The failure is rarely dramatic. A customer’s delivery address is corrected in the CRM at 10:41 and in the ERP at 10:43, and the older value wins. A price is updated in the ERP while a promotion is applied in the storefront, and one of them silently disappears. Nobody notices for weeks, because both systems continue to look internally consistent.

If your integration does not have a written answer to “who wins”, it has an answer anyway — and it is whichever system happened to be slower.

Rule one: name a source of truth per field, not per system

The instinct is to declare one system authoritative for a whole record type: the ERP owns products, the CRM owns customers. In practice authority is finer-grained than that. The ERP owns cost price and stock; the storefront owns the marketing description and the images. The CRM owns the marketing consent flag; the ordering system owns the delivery address used on the last shipment.

Write this down as a table during discovery, one row per field, with exactly one owning system in each row. Any field where two people argue about the owner is a field that will cause a production incident later — resolve it on paper, before the build.

Rule two: choose an explicit conflict strategy

Once ownership is agreed, the remaining conflicts need a deterministic strategy. There are four that cover almost every case, and the choice should be recorded per field group rather than assumed.

  • Owner wins — the owning system’s value is always applied, and updates from the other side are rejected and logged. Correct for cost price, stock and tax codes.
  • Last write wins, with a trusted clock — acceptable only where both systems emit reliable modification timestamps and the field is low-risk. Never use the receiving system’s own clock.
  • Merge by field — each field is evaluated independently against its owner, so a single record can accept changes from both sides in the same cycle. This is the correct default for customer records.
  • Quarantine for review — the conflicting record is parked in an exception queue and a human decides. Appropriate for anything financial, and for any conflict the other three rules cannot resolve.

Rule three: break the echo loop before it starts

A two-way sync will happily talk to itself. System A pushes a change to system B; B fires its own update webhook; A receives it and applies it as a fresh change, pushing again. In a busy hour this can consume your entire API quota and leave both systems oscillating between two values.

There are two reliable defences, and production integrations use both. First, stamp every write with an origin marker — an integration user account, a metafield, or a custom header — and ignore inbound events carrying your own marker. Second, compare a hash of the mapped fields before writing: if nothing you care about has changed, do not write at all. Together these reduce transfer volume dramatically, which also happens to keep you within rate limits.

Rule four: make every decision provable after the fact

The value of conflict rules is not only that they produce the right answer, but that they let you demonstrate why an answer was produced three months later, when a disputed order becomes an argument between two departments. That means logging the inbound payload, the rule that was applied, the value before and the value after, against a stable record identifier.

This is also what makes an integration safe to change. With a decision log, a new rule can be shadow-run against historic conflicts to see what it would have done differently. Without one, every change to the logic is a leap of faith.

A short checklist before you build

Before a line of code is written, four artefacts should exist: a field-level ownership table, a conflict strategy per field group, an echo-loop defence for each direction, and a specification of what the decision log records. None of them takes long. All of them are considerably cheaper than discovering the gap in production.

Two-way sync is not twice the work of one-way sync. It is one-way sync plus a set of decisions — and the decisions are the part worth paying for.