Route 53 Active-Active Multi-Region DNS load balancing is less about distributing traffic evenly and more about providing uninterrupted service during a full regional outage.

Imagine you have two identical web applications, one running in us-east-1 and another in eu-west-1. You want Route 53 to direct users to whichever region is available.

# Example Route 53 Health Check for us-east-1
aws route53 create-health-check \
    --caller-reference "my-app-us-east-1-$(date +%s)" \
    --health-check-config \
        Type=HTTPS,FullyQualifiedDomainName=app.example.com,RequestInterval=30,FailureThreshold=3,RequestTimeout=10,Port=443,ResourcePath=/health,Inverted=false,EnableSNI=true,Regions=us-east-1 \
    --health-check-id

# Example Route 53 Health Check for eu-west-1
aws route53 create-health-check \
    --caller-reference "my-app-eu-west-1-$(date +%s)" \
    --health-check-config \
        Type=HTTPS,FullyQualifiedDomainName=app.example.com,RequestInterval=30,FailureThreshold=3,RequestTimeout=10,Port=443,ResourcePath=/health,Inverted=false,EnableSNI=true,Regions=eu-west-1 \
    --health-check-id

# Example Route 53 Record Set Group for us-east-1
aws route53 change-resource-record-sets \
    --hosted-zone-id Z1XXXXXXXXXXXXXX \
    --change-batch '{
        "Comment": "Active-Active US East 1 Record",
        "Changes": [
            {
                "Action": "UPSERT",
                "ResourceRecordSet": {
                    "Name": "app.example.com.",
                    "Type": "A",
                    "SetIdentifier": "us-east-1-active",
                    "Weight": 100,
                    "AliasTarget": {
                        "HostedZoneId": "Z3XXXXXXXXXXXXXX",
                        "DNSName": "dualstack.my-alb-us-east-1.amazonaws.com.",
                        "EvaluateTargetHealth": false
                    },
                    "Failover": "PRIMARY",
                    "HealthCheckId": "hc-xxxxxxxxxxxxxx"
                }
            }
        ]
    }'

# Example Route 53 Record Set Group for eu-west-1
aws route53 change-resource-record-sets \
    --hosted-zone-id Z1XXXXXXXXXXXXXX \
    --change-batch '{
        "Comment": "Active-Active EU West 1 Record",
        "Changes": [
            {
                "Action": "UPSERT",
                "ResourceRecordSet": {
                    "Name": "app.example.com.",
                    "Type": "A",
                    "SetIdentifier": "eu-west-1-active",
                    "Weight": 100,
                    "AliasTarget": {
                        "HostedZoneId": "Z4XXXXXXXXXXXXXX",
                        "DNSName": "dualstack.my-alb-eu-west-1.amazonaws.com.",
                        "EvaluateTargetHealth": false
                    },
                    "Failover": "SECONDARY",
                    "HealthCheckId": "hc-yyyyyyyyyyyyyy"
                }
            }
        ]
    }'

Here’s how it works: you create two A records for the same DNS name (app.example.com). Each record points to the load balancer in a different region (us-east-1 and eu-west-1). Crucially, each record is associated with a Route 53 health check that monitors the health of the application in its respective region.

The Failover setting is key. One record is marked PRIMARY and the other SECONDARY. Route 53’s global network of DNS servers continuously checks the health of both endpoints via the associated health checks. If the PRIMARY endpoint (in us-east-1) becomes unhealthy, Route 53 automatically starts returning only the IP addresses for the SECONDARY endpoint (in eu-west-1). Users’ DNS queries will then be directed to the healthy region.

The Weight parameter is set to 100 for both records here, which is typical for an active-active setup where you don’t want to pre-emptively bias traffic. Route 53 doesn’t use Weight for failover itself; that’s handled by Failover. Instead, if Failover wasn’t configured and both were healthy, Route 53 would use Weight to distribute traffic. In a pure active-active failover scenario, you’d typically want Weight to be equal, so that when both are healthy, traffic is distributed based on latency or geolocation (if configured).

The EvaluateTargetHealth is set to false because we are explicitly managing health via the HealthCheckId on the record set itself. If this were true, Route 53 would look at the health of the target resource (e.g., the ALB’s target groups), but for multi-region failover, you want explicit control over the health check that triggers the failover.

The most surprising thing is that even with Failover configured, Route 53 will still return both IP addresses if both health checks pass. It’s up to the client making the DNS query to resolve both and potentially choose one. This means you need to configure your client applications or your network infrastructure (like a global load balancer or edge network) to handle multiple IP addresses and select the best one, usually based on latency. A common pattern is to use A records with Failover and Weight set to 100 for both, and then rely on the client’s DNS resolver to pick the lowest latency IP among the healthy ones.

The next step is to understand how Route 53’s latency-based routing can further optimize which healthy region a user is directed to.

Want structured learning?

Take the full Route53 course →