How does Couchbase XDCR resolve conflicts between two clusters that both accepted writes?
answer
- Both sides must reach the same verdict
- Chosen at bucket creation, never later
- One compares revisions, the other clocks
- Timestamp mode needs NTP everywhere
- The loser is discarded, not merged
basics
~10 sXDCR resolves conflicts deterministically per document using the bucket's conflict-resolution mode, fixed at bucket creation: sequence-number (revision metadata) or timestamp last-write-wins. Both clusters pick the same winner and converge; the losing version is discarded.
solid answer
~50 sXDCR (Cross Data Center Replication) is asynchronous, source-driven, per-bucket replication between Couchbase clusters, built on DCP streams with checkpoints so it can pause and resume. Bidirectional replication is just two unidirectional links, which means the same document can be written on both sides and the two versions must be reconciled. Couchbase does this per document with a **conflict-resolution mode chosen when the bucket is created and immutable afterwards**, and both ends must use the same mode. **Sequence-number** mode compares the document's revision metadata — the number of mutations it has seen, then CAS, then expiry and flags — and picks a winner deterministically without any clock. **Timestamp (LWW)** mode compares the CAS value, which is derived from a hybrid logical clock, so the later wall-clock write wins — and it requires tightly synchronised clocks across both clusters. Either way the decision is the same on both sides, so the clusters converge, and the loser is discarded, not merged.
code
bash · 9 lines# Conflict-resolution mode is fixed when the bucket is created
curl -u Administrator:$PASS -X POST http://source:8091/pools/default/buckets \
-d name=orders -d bucketType=couchbase -d ramQuotaMB=1024 \
-d replicaNumber=2 -d conflictResolutionType=seqno
# One direction of an XDCR link; run the mirror image on the other cluster
curl -u Administrator:$PASS -X POST http://source:8091/controller/createReplication \
-d fromBucket=orders -d toCluster=dr-cluster -d toBucket=orders \
-d replicationType=continuousgo deeper
Know that XDCR copies documents between Couchbase clusters asynchronously, and that when both clusters write the same document one version wins and the other is dropped.
Explain the two conflict-resolution modes and what each compares — revision metadata with no clock involved, versus CAS-derived timestamps — and that the mode is set when the bucket is created.
Demonstrate the production angles: deletes participate in conflict resolution, replication lag is your data-loss window, clock discipline is a prerequisite for LWW, and no durability level extends across clusters.
Own the design decision — which documents may be written in more than one region at all, what the conflict semantics cost the business, and whether single-writer routing removes the problem instead of resolving it.
## What XDCR is **Cross Data Center Replication** copies documents from a bucket on one Couchbase cluster to a bucket on another. It is configured on the source and pushes to the target; it reads mutations from the source's **DCP** stream and applies them remotely, keeping checkpoints so a paused or interrupted replication resumes rather than restarting. It replicates *data*, not cluster configuration: bucket settings, GSI index definitions and users must be created on the target yourself. In Couchbase 7.x replications are defined with explicit scope and collection mapping, and filter expressions can restrict which documents flow. The key property for everything below: XDCR is **asynchronous**. The source acknowledges the client's write on its own terms (including durability levels, which are intra-cluster only) and replication happens afterwards, with a queue and a measurable lag. ## Where conflicts come from Unidirectional XDCR to a passive target has no conflicts as long as nothing else writes the target. The moment you set up the reverse direction too — bidirectional replication is literally two unidirectional replications — both clusters accept writes to the same key space. Two clients can update the same document in two regions within the replication lag window, and neither cluster knew about the other's write when it accepted its own. That is a conflict, and it must be resolved identically on both sides or the clusters permanently diverge. ## Mode one: sequence-number (revision-based) This is the default. Every document carries revision metadata that Couchbase maintains: a revision sequence number that increments with each mutation, plus the CAS value, plus expiry and flags. When an incoming XDCR mutation meets an existing local document, the receiving cluster compares this metadata in a fixed precedence order — revision sequence number first, then CAS, then the remaining fields as tie-breakers — and keeps the winner. The important property is that the comparison uses no wall-clock time and produces the same verdict wherever it is evaluated. Practically, the document that has been mutated more times tends to win, which is a reasonable heuristic but is **not** "the newest write wins": a document updated twice in a quiet region beats a single later update in a busy one. ## Mode two: timestamp (last-write-wins) In LWW mode the comparison is on the CAS value, which Couchbase derives from a hybrid logical clock incorporating wall-clock time. The later timestamp wins, which is the intuitive semantic — and it buys that intuition with a hard operational dependency: **the clocks on all nodes in both clusters must be synchronised**, in practice with NTP and active monitoring of drift. If a node's clock runs ahead, the writes it stamps beat genuinely later writes from correctly-clocked nodes, and the newer data is silently thrown away. If a clock jumps backwards, that node's writes can be ignored entirely. Because the mode is baked in at bucket creation and cannot be changed, and because both ends of a replication must agree on it, this is a decision made before a single document exists — a genuinely load-bearing schema-time choice. ## Deletes Deletions replicate as tombstones and participate in conflict resolution like any other mutation. A delete can therefore *lose* to a concurrent update and the document stays alive, or win and remove a concurrent update's data. "I deleted it and it came back" is a real bidirectional-XDCR support case, not a myth. ## Convergence, not merging XDCR never merges two versions field by field. One whole document version wins and the other is discarded. If your application semantics need both sides' changes preserved — a set of items, a running total, a comment list — the model has to make that safe at the document level: split contended state into per-region documents, use append-style keys, or keep the contended write in one region only. Expecting the database to do a semantic merge is the most common design failure here. ## Operational reality What you monitor is replication lag — the backlog of changes not yet sent — because that backlog is your data-loss window if the source region disappears. What you test is the conflict path, deliberately, before production. And what you write down is which documents may be written in more than one region, because that set is where every conflict will come from. ## Interview traps Candidates often assume LWW is the default (it is not), that the mode can be flipped later (it cannot), that XDCR merges documents (it does not), or that a strong local durability level implies the write reached the other cluster (it does not).
- Why is timestamp (LWW) conflict resolution risky in Couchbase XDCR?It decides winners from CAS values derived from wall-clock time, so correctness depends on clock synchronisation across every node in both clusters. A node whose clock runs fast stamps writes that beat genuinely later writes elsewhere, and the newer data is discarded silently — no error, no conflict record. It needs disciplined NTP plus drift monitoring, and it is only worth it when "latest write wins" is genuinely the semantic you want.
- Can you change a Couchbase bucket's conflict-resolution mode after it has data?No — the mode is fixed at bucket creation, and both ends of an XDCR replication must use the same one. Changing it means creating a new bucket with the desired mode and migrating the data, then rebuilding the replications. That makes it a decision to make deliberately at design time, alongside replica count, rather than something to revisit when conflicts start appearing in production.
- How does an application avoid XDCR conflicts entirely while still running two regions?Give every document a single writer. Route each user, tenant, or key range to a home region and only write it there, with the other region readable and ready to take over; or split contended state into per-region documents that are aggregated on read. That keeps bidirectional XDCR as a resilience mechanism rather than a merge engine, and conflict resolution becomes the safety net for failover windows instead of a routine code path.
saying these in an interview costs you the question
- Assumes last-write-wins is the default XDCR mode
- Thinks XDCR merges two document versions field by field
- Believes the conflict-resolution mode can be changed later
- Runs timestamp mode without synchronised clocks
- Says a durable local write is guaranteed present on the target cluster