# Cross-datacenter replication (XDR)

Cross-Datacenter Replication (XDR) asynchronously replicates data between independent Aerospike clusters, enabling disaster recovery, global distribution, and high availability across cloud regions.

## Overview

XDR synchronizes data between geographically distributed Aerospike Cloud clusters over higher-latency links. This protects your data against cloud region failure and enables high-performance, geo-distributed applications with low-latency access at each cluster location.

### Key concepts

-   **Source cluster**: The cluster from which records are shipped
-   **Destination cluster**: The cluster to which records are shipped
-   **Shipping**: The process of sending data from one cluster to another
-   **Active cluster**: Receives application writes directly
-   **Passive cluster**: Receives writes only through XDR replication

### Use cases

| Use case | Description |
| --- | --- |
| **Disaster recovery** | Replicate data to a remote region for failover if the primary region becomes unavailable |
| **Global distribution** | Reduce latency by placing data closer to users in different geographic regions |
| **Load balancing** | Distribute read requests across multiple clusters |
| **Data migration** | Facilitate smooth transitions between clusters or regions |

## Supported topologies

XDR supports several replication topologies to match your requirements:

### Active-passive

Clients write to a single active cluster, which replicates to one or more passive clusters. The passive cluster serves as a hot standby for disaster recovery or can offload read-intensive workloads.

### Active-active (mesh)

Both clusters accept writes and replicate to each other. Best suited when writes to the same record are unlikely to occur simultaneously in both clusters—for example, when users are geographically partitioned.

::: caution
In active-active topologies, simultaneous writes to the same record in different clusters can cause conflicts. While [bin convergence](https://aerospike.com/docs/database/manage/xdr/convergence) helps resolve conflicts, it ensures convergence, not strict consistency. Some intermediate updates may be lost.
:::

### Star topology

A central cluster replicates to multiple destination clusters simultaneously. Commonly used to publish data from a central location to multiple regions for low-latency read access.

## Replication granularity

You can control what data gets replicated:

| Level | Description |
| --- | --- |
| **Namespace** | Replicate all data in a namespace (default for Aerospike Cloud) |
| **Set** | Replicate only specific sets within a namespace |
| **Record deletes** | Optionally replicate client deletes; NSUP deletes (expiration/eviction) are not shipped by default |

For set-level filtering, use the `ship-only-specified-sets` and `ship-set` parameters in your XDR configuration.

## Prerequisites

Before configuring XDR in Aerospike Cloud:

-   Two or more Aerospike Cloud clusters with non-overlapping CIDR blocks
-   VPC peering established between clusters
-   Database credentials configured on destination clusters
-   Secrets configured to store credential passwords
-   Access to the Aerospike Cloud API (API key created)

## Configuration

### Step 1: Establish VPC peering

Connect your clusters through VPC peering to enable private network communication.

-   [Console](#tab-panel-685)
-   [API](#tab-panel-686)

1.  Navigate to the passive cluster’s **Networking** tab.
2.  Click **Set up network access**.
3.  Enter the active cluster’s VPC information:
    -   Account ID
    -   VPC ID
    -   CIDR block
    -   Region

::: note
Contact your Aerospike representative to complete the VPC peering setup between clusters. Provide the UUIDs of both clusters.
:::

Retrieve the active cluster’s infrastructure metadata:

Terminal window

```bash
curl -X GET "https://api.aerospike.cloud/v2/databases/<active-database-id>" \

    -H "Authorization: Bearer $TOKEN" \

    -H "Content-Type: application/json" | jq '.infrastructure'
```

Create the VPC peering connection from the passive cluster:

Terminal window

```bash
curl -X POST "https://api.aerospike.cloud/v2/databases/<passive-database-id>/vpc-peerings" \

    -H "Authorization: Bearer $TOKEN" \

    -H "Content-Type: application/json" \

    --data '{

        "vpcId": "<active-database-vpc-id>",

        "cidrBlock": "<active-database-cidr-block>",

        "accountId": "<active-database-account-id>",

        "region": "<active-database-region>",

        "isSecureConnection": true

    }'
```

### Step 2: Create destination credentials

Create database credentials on the destination (passive) cluster for XDR authentication.

-   [Console](#tab-panel-679)
-   [API](#tab-panel-680)

1.  Navigate to the passive cluster’s **Access manager** tab.
2.  Click **Add user**.
3.  Create a user with the **read-write** role.
4.  Save the password—it is displayed only once.

Terminal window

```bash
curl -X POST "https://api.aerospike.cloud/v2/databases/<passive-database-id>/credentials" \

    -H "Authorization: Bearer $TOKEN" \

    -H "Content-Type: application/json" \

    --data '{"name": "<username>", "roles": ["read-write"], "password": "<password>"}'
```

### Step 3: Store the password as a secret

Create a secret to securely store the destination credential password.

-   [Console](#tab-panel-681)
-   [API](#tab-panel-682)

1.  Navigate to **Team Settings** > **Secrets**.
2.  Click **Add secret**.
3.  Enter a name and set the value to the credential password.

Terminal window

```bash
curl -X POST "https://api.aerospike.cloud/v2/secrets" \

    -H "Authorization: Bearer $TOKEN" \

    -H "Content-Type: application/json" \

    --data '{"name": "<secret-name>", "description": "", "value": "<password>"}'
```

### Step 4: Configure XDR on the source cluster

Add the XDR configuration to the active cluster to enable replication.

-   [Console](#tab-panel-683)
-   [API](#tab-panel-684)

1.  Navigate to the active cluster and click **Edit server config**.
    
2.  Add an `xdr` block at the same level as `namespaces`:
    
    ```json
    {
    
        "namespaces": [...],
    
        "xdr": {
    
            "dcs": [{
    
                "name": "passive-dc",
    
                "auth-mode": "internal",
    
                "auth-user": "<username>",
    
                "auth-password-file": "<secret-ref>",
    
                "node-address-ports": [
    
                    "<passive-cluster-id>.aerospike.internal 4000 <passive-db-id>.aerospike.internal"
    
                ],
    
                "tls-name": "<this-cluster-id>.aerospike.internal",
    
                "namespaces": [{
    
                    "name": "default"
    
                }]
    
            }]
    
        }
    
    }
    ```
    
    ::: note
    The `node-address-ports` value is a space-separated string: `<hostname> <tls-port> <tls-name>`.
    :::
    

Terminal window

```bash
curl -X PATCH "https://api.aerospike.cloud/v2/databases/<active-database-id>" \

    -H "Authorization: Bearer $TOKEN" \

    -H "Content-Type: application/merge-patch+json" \

    --data '{

        "aerospikeServer": {

            "xdr": {

                "dcs": [{

                    "name": "passive-dc",

                    "auth-user": "<username>",

                    "auth-password-file": "<secret-ref>",

                    "auth-mode": "internal",

                    "tls-name": "<this-cluster-id>.aerospike.internal",

                    "node-address-port": "<passive-db-id>.aerospike.internal 4000 <passive-db-id>.aerospike.internal",

                    "namespaces": [{

                        "name": "default"

                    }]

                }]

            }

        }

    }
```

## XDR configuration parameters

| Parameter | Description |
| --- | --- |
| `name` | Identifier for the destination datacenter. |
| `auth-mode` | Authentication mode: `internal` for Aerospike access control. |
| `auth-user` | Username with read-write permissions on the destination. |
| `auth-password-file` | Reference to the secret containing the password. |
| `node-address-ports` | Destination hostname, TLS port, and TLS name. |
| `tls-name` | TLS certificate name for secure connections. For more information about TLS configuration, see [TLS configuration](https://aerospike.com/docs/database/manage/network/tls). |
| `namespaces` | List of namespaces to replicate. |

For set-level filtering within a namespace, add the following parameters to the namespace configuration:

```json
"namespaces": [{

    "name": "default",

    "ship-only-specified-sets": true,

    "ship-set": ["set1", "set2"]

}]
```

## Verify replication

After configuration, verify XDR is working:

1.  Write data to the active cluster using your application or the Aerospike Cloud quickstart tools.
2.  Monitor the passive cluster’s metrics (such as disk usage) in the console—they should increase proportionally to data written to the active cluster.

## Extended topologies

Once you have active-passive replication working, you can extend to more complex topologies:

| Topology | Configuration |
| --- | --- |
| **Star** | Add additional destination clusters by repeating the passive cluster setup |
| **Active-active** | Configure XDR on both clusters, each pointing to the other as a destination |

## Related resources

-   [XDR architecture](https://aerospike.com/docs/database/learn/architecture/xdr/)
-   [XDR set policy](https://aerospike.com/docs/database/manage/xdr/set-policy/)
-   [Bin convergence](https://aerospike.com/docs/database/manage/xdr/convergence/)
-   [Aerospike Cloud quickstart](https://aerospike.com/docs/cloud/quickstart)