Couchbase XDCR Unidirectional Replication: Setup and Conflict Handling
Set up unidirectional Couchbase XDCR to replicate a bucket to a remote cluster, choose conflict resolution, and verify status before failover.
04 Nov 2025, 16:27 UTC

The Problem: Keeping a Remote Bucket in Sync
If your application runs in one data center but needs read access or disaster recovery in another, copying documents manually or writing application-level dual writes creates inconsistency and conflict risk. Couchbase Cross Datacenter Replication (XDCR) streams changes from a source bucket to a target cluster at the database level. The useful takeaway: configure unidirectional replication from source to target, use sequence-number conflict resolution unless you need custom logic, and verify replication status before you rely on the target for failover.
Version Assumptions and Network Requirements
This guide assumes Couchbase Server 7.x or later. XDCR uses the cluster management port (typically 8091), the data port (11210), and the replication port (typically 9999 or 11210 depending on version). The source and target clusters must reach each other over these ports. Bucket names can differ, but using the same name avoids mapping confusion.
Create a Remote Cluster Reference
Run this from a host that can reach both clusters' management endpoints. You need Full Admin or Cluster Admin credentials.
curl -u CLUSTER_USER:CLUSTER_PASS -X POST http://SOURCE_CLUSTER:8091/pools/default/remoteClusters \
-d name=TARGET_CLUSTER_ALIAS \
-d hostname=TARGET_CLUSTER_HOST:8091 \
-d username=TARGET_CLUSTER_USER \
-d password=TARGET_CLUSTER_PASS
Replace placeholders with actual values. Expected check: a successful response contains the cluster reference name and UUID. Risk: if the target hostname is unreachable or credentials are wrong, the request fails and no replication stream starts.
Create the Replication
curl -u CLUSTER_USER:CLUSTER_PASS -X POST http://SOURCE_CLUSTER:8091/controller/createReplication \
-d fromBucket=SOURCE_BUCKET \
-d toCluster=TARGET_CLUSTER_ALIAS \
-d toBucket=TARGET_BUCKET \
-d replicationType=unidirectional \
-d conflictResolution=seqno
Where to run: same host as the previous command, with network access to the source cluster's management port. Required permissions: Full Admin on the source cluster. Expected check: the response returns a replication ID. You can then list replications with:
curl -u CLUSTER_USER:CLUSTER_PASS http://SOURCE_CLUSTER:8091/pools/default/replications
Conflict Resolution: Sequence Number vs Custom
When the same document is updated on both clusters, XDCR must decide which version wins. Couchbase offers two established options:
| Policy | Behavior | When to use |
|---|---|---|
| Sequence number (seqno) | The update with the higher sequence number on the source wins. | Unidirectional replication where the source is authoritative. |
| Custom conflict resolution | A server-side function compares document fields, such as a timestamp, before applying the change. | Bidirectional scenarios or when business logic must determine the winner. |
For a one-way disaster-recovery stream, seqno is simpler and avoids running custom functions on every mutated document. Custom resolution adds CPU overhead and requires the function to exist on both clusters.
Verifying Replication Health
Check the replication status from the source cluster:
curl -u CLUSTER_USER:CLUSTER_PASS http://SOURCE_CLUSTER:8091/pools/default/replications/REPLICATION_ID
Look for fields such as status (should be replicating), docs_checkpointed increasing over time, and docs_remaining trending toward zero after a quiet period. A practical check before cutover: compare document counts on source and target using the Web Console or a N1QL SELECT COUNT(*) query on both buckets. Counts may differ briefly during active writes, but they should converge when writes stop.
Limits and Common Mistakes
- Bidirectional loops: Replicating bucket A to B and bucket B to A on the same document set can cause endless change propagation unless conflict resolution and application logic prevent it. Prefer unidirectional replication for disaster recovery.
- Checkpoint memory: XDCR keeps checkpoints in memory to track replicated mutations. High write volume on the source can consume significant RAM on both clusters before checkpoints are discarded.
- Indexes do not replicate: Secondary indexes and full-text indexes on the source are not copied to the target. Create them separately on the target cluster if queries need them there.
- Firewall ports: Blocked management or data ports cause silent replication stalls. Verify connectivity before creating the replication.
Removing a Replication
Because creating a replication changes cluster state, you can remove it when no longer needed:
curl -u CLUSTER_USER:CLUSTER_PASS -X DELETE http://SOURCE_CLUSTER:8091/controller/cancelReplication/REPLICATION_ID
Expected check: the replication disappears from the replications list. Risk: stopping replication leaves the target bucket stale; any writes made on the target after the stop point are not sent back to the source.
Practical Cutover Check
Before failing over to the target cluster, stop writes to the source, wait for docs_remaining to reach zero, then compare counts. If the target lags, investigate network throughput and checkpoint memory rather than promoting a stale dataset.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.