Skip to content
AWS aws dns-cdn 6 min read

Route 53 Routing Policies

Amazon Route 53 is the AWS managed DNS (Domain Name System — the service that turns names like app.example.com into IP addresses) service. A routing policy is the rule Route 53 uses to decide which answer to return when many records share the same name. This is how you do A/B testing, send users to the closest Region, or fail over to a backup when something breaks. This page walks through each policy, when to reach for it, and the one gotcha that trips up almost everyone: DNS answers are cached, so routing changes are never truly instant.

How a routing policy fits in

When you create a record (say, an A record for www.example.com) you must choose a routing policy. With simple routing there is one answer and Route 53 always returns it. With every other policy you create multiple records with the same name and type, and the policy tells Route 53 how to pick among them per query. Resolvers (the DNS servers your users’ computers talk to) then cache that answer for the record’s TTL (Time To Live — how many seconds an answer may be reused before asking again).

Routing policies steer DNS answers. They do not proxy or move traffic themselves — once a client has an IP, Route 53 is out of the loop until the cached answer expires. That is why low TTLs and health checks matter so much.

The routing policies at a glance

PolicyWhat it doesClassic use caseWhen NOT to use
SimpleReturns one record (or all values, randomly ordered)A single endpoint with no logicAny time you need health checks or steering
WeightedSplits answers by a numeric weightA/B testing, blue/green rolloutWhen you need exact per-user splits
Latency-basedReturns the Region with lowest network latency to the userMulti-Region apps wanting speedSingle-Region apps
GeolocationRoutes by the user’s continent/country/stateCompliance, localized contentWhen latency, not geography, is the goal
GeoproximityRoutes by geographic distance, with an adjustable “bias”Shifting traffic between Regions by region sizeSimple cases (use latency instead)
FailoverPrimary/secondary; secondary only on health-check failureDisaster recovery (DR)Active-active designs (use weighted/latency)
Multivalue answerReturns up to 8 healthy records, randomizedCheap client-side load spreadingTrue load balancing (use an ALB/NLB)

Weighted routing — A/B and blue/green

Weighted routing assigns each record a weight from 0 to 255. Route 53 returns a record proportional to its share of the total weight. Two records weighted 90 and 10 send roughly 90% and 10% of resolutions to each. Setting a weight to 0 stops a record from being served (handy to drain a version).

When to use it: gradual rollouts (shift 5% of traffic to a new version, watch metrics, ramp up) or simple A/B experiments.

When NOT to use it: when you need a precise per-user split. Because of caching, the ratio is an approximation across many resolvers over time, not a coin flip per visitor.

Console steps:

  1. Open the Route 53 console, choose Hosted zones, and select your zone.
  2. Click Create record, enter the name (e.g. app), choose type A.
  3. Set Routing policy to Weighted, enter the value/alias, a Weight (e.g. 90), and a unique Record ID (e.g. prod-v1).
  4. Repeat to add the second record with weight 10 and a different Record ID.

CLI equivalent (CLI v2). Save this change batch and apply it:

aws route53 change-resource-record-sets \
  --hosted-zone-id Z0123456789ABCDEFGHIJ \
  --change-batch '{
    "Changes": [{
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "app.example.com",
        "Type": "A",
        "SetIdentifier": "prod-v1",
        "Weight": 90,
        "TTL": 60,
        "ResourceRecords": [{ "Value": "203.0.113.10" }]
      }
    }]
  }'

Output:

{
    "ChangeInfo": {
        "Id": "/change/C0987654321ZYXWVUTSRQ",
        "Status": "PENDING",
        "SubmittedAt": "2026-06-15T10:04:11.000Z"
    }
}

Latency-based routing — fast multi-Region apps

Latency-based routing returns the record in the AWS Region with the lowest measured network latency to the resolver. If you run the same app in us-east-1 and eu-west-1, a user in Frankfurt is sent to Europe and a user in Virginia to the US.

When to use it: identical stacks deployed in multiple Regions where speed matters. When NOT to use it: single-Region apps, or when law requires geographic routing (use geolocation instead). Each latency record carries a Region field rather than a weight.

aws route53 change-resource-record-sets \
  --hosted-zone-id Z0123456789ABCDEFGHIJ \
  --change-batch '{
    "Changes": [{
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "app.example.com",
        "Type": "A",
        "SetIdentifier": "eu-west-1",
        "Region": "eu-west-1",
        "TTL": 60,
        "ResourceRecords": [{ "Value": "198.51.100.20" }]
      }
    }]
  }'

Geolocation and geoproximity

Geolocation routes by where the query comes from — continent, country, or US state. Use it for compliance (“EU users must hit EU servers”) or localized content (language, currency). Always create a Default location record to catch users that match no rule, or those queries return no answer.

Geoproximity routes by physical distance to your resources and adds a bias (-99 to +99) that grows or shrinks a Region’s geographic reach. Use it when you want to shift load between Regions (e.g. send more traffic to a larger data center). It requires Route 53 traffic flow policies.

Failover routing — disaster recovery

Failover routing pairs a primary record with a secondary. Route 53 serves the primary while its associated health check passes; when the health check fails, it serves the secondary. This is the standard active-passive DR pattern: primary in your main Region, secondary pointing at a static “we’ll be right back” page or a warm standby.

aws route53 change-resource-record-sets \
  --hosted-zone-id Z0123456789ABCDEFGHIJ \
  --change-batch '{
    "Changes": [{
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "app.example.com",
        "Type": "A",
        "SetIdentifier": "primary",
        "Failover": "PRIMARY",
        "TTL": 30,
        "HealthCheckId": "abcd1234-5678-90ef-ghij-1234567890ab",
        "ResourceRecords": [{ "Value": "203.0.113.10" }]
      }
    }]
  }'

Gotcha — failover is not instant. Even after a health check fails, resolvers and browsers keep serving the cached IP until the TTL expires. With a 300-second TTL, users can hit the dead endpoint for up to 5 minutes. Use a low TTL (30-60s) on failover and weighted records, and always attach health checks. Lower TTLs mean more queries (Route 53 charges per million standard queries, roughly $0.40), but for failover the trade is worth it.

Multivalue answer routing

Multivalue answer routing returns up to 8 healthy records in random order, letting the client pick one. It is a cheap way to spread requests and avoid dead endpoints, but it is not a load balancer — there’s no traffic-aware distribution, just randomized DNS answers with health checks. Use it for simple fault tolerance; use an Application/Network Load Balancer when you need real load balancing.

Best Practices

  • Keep TTLs low (30-60s) on failover, weighted, and latency records so changes propagate quickly.
  • Always attach Route 53 health checks to failover and multivalue records, and add a Default record to geolocation sets.
  • Treat weighted ratios as approximate across resolvers, not exact per-user splits — verify with real metrics, not the weights alone.
  • Use latency-based routing for speed and geolocation for compliance; don’t confuse the two.
  • Start blue/green rollouts at a small weight (e.g. 5%), watch CloudWatch metrics, then ramp.
  • Use alias records (free, no query charge) to point at AWS resources like ALBs and CloudFront instead of hardcoded IPs where possible.
Last updated June 15, 2026
Was this helpful?