06 / 16
Cloud Codex · AWS / 06

Route 53.

AWS's managed authoritative DNS. The day-one usage is "host a zone and point records at things." The reason it's interesting is the seven routing policies and the health-check machinery — Route 53 is how you do regional failover, latency-based steering, weighted blue/green, and gradual rollouts at the DNS layer for traffic that hasn't reached your load balancer yet.


1 · What Route 53 actually is (and isn't)

The mental model that survives every conversation: Route 53 is a globally-distributed authoritative DNS service running on AWS edge POPs, with health checks and routing policies bolted on top. The "53" is the DNS port, in case it ever felt opaque. Two surfaces, very different scaling properties: an authoritative resolver fleet that answers queries from public recursive resolvers, and a control plane that lets you write zones and records into it.

The authoritative fleet runs anycast at AWS's edge: every Route 53 nameserver IP is announced from multiple POPs worldwide, and BGP routes recursive resolvers to whichever instance is topologically closest. When a resolver looks up example.com and gets back four NS records — typically named ns-NNN.awsdns-NN.com, .net, .org, .co.uk — each of those names independently anycasts to many physical instances. The four-TLD diversity is deliberate; it ensures resolvability survives a single TLD's resolver outage.

Route 53 has a 100% SLA on its authoritative DNS service. AWS gives that level of guarantee to vanishingly few products (and refunds 100% of charges for the month if the DNS service fails to respond to a single query). That's not marketing fluff — it's a load-bearing property: Route 53 is so structurally redundant via anycast + shuffle sharding that AWS is comfortable paying out its entire revenue any time it fails.

What Route 53 isn't: a recursive resolver (it's authoritative-only — your laptop doesn't query Route 53 directly, it queries an ISP/Google/Cloudflare resolver that then queries Route 53). It isn't a load balancer (no visibility into request bodies, no health between requests on the same connection). It isn't a CDN (no caching of HTTP responses). And critically, it isn't synchronous — when you change a record, recursive resolvers worldwide will return the old value for as long as their TTL says they can.

Route 53 is good forRoute 53 is bad for
Multi-region failover and active-active steering (latency + failover + health checks)Sub-second failover (DNS TTL bounds the floor — typically 60s+ in practice)
Weighted blue/green deployments at the DNS layerPer-request routing decisions (use a load balancer)
Private service discovery inside VPCs (private hosted zones; ECS Cloud Map)Workloads where resolver caching breaks your assumptions (mobile clients with aggressive resolver caches)
Alias records that follow ALB/CloudFront/S3 IPs without you tracking themApex-CNAME workarounds — use Alias instead, which is what alias was built for
Anything where the 100% SLA actually matters (regulated, customer-facing critical infra)Geolocation routing when half your users are on VPNs (the resolver IP, not the client, determines geo)

2 · How a DNS query reaches Route 53 — the full path

Most engineers carry a sketch of "DNS does recursive lookups" in their head; the version that's load-bearing for understanding Route 53 is more specific. The anycast routing and TLD diversity only matter once you see where they slot in.

Two practical consequences. First, your client never talks to Route 53 directly. It talks to a recursive resolver (the ISP's, Cloudflare's 1.1.1.1, Google's 8.8.8.8, or your corporate resolver), which in turn talks to Route 53. The recursive resolver does the caching — and you have no control over its cache policy. Setting a TTL of 1 second won't make resolvers honour it; many cap effective TTLs to 30–60s regardless of what your zone says. Second, anycast means "geographically near," not "fast". A client in Tokyo gets routed to the closest POP by BGP topology, which usually but not always matches latency. AWS publishes latency measurements between regions/POPs and uses them for latency-based routing, but the recursive resolver's location (not the client's) is what they actually see.

3 · Shuffle sharding — why Route 53 is so hard to break

A core reason Route 53 sustains a 100% SLA is shuffle sharding, a technique AWS principal engineer Colm MacCárthaigh has written about extensively. The classic version: instead of every customer's zone living on the same nameservers, each customer gets four NS records chosen randomly from a much larger pool. With a pool of, say, 2,048 nameservers and 4 picked per customer, two random customers share any nameserver with vanishingly small probability — and share all four with effectively zero. A poisoned, overloaded, or otherwise broken nameserver hurts the customers that happen to use it, but the blast radius is tiny rather than total.

This is why the famous Route 53 incidents (rare, brief, never region-wide) tend to affect only a slice of customers rather than the whole service — and why the SLA can credibly be 100%. The same shuffle-sharding idea reappears in AWS's design of other globally-critical services; if you ever wondered why your zone's NS records look randomly chosen, that's why.

4 · Zones, records, alias

A hosted zone is Route 53's container for one domain — example.com and its subdomains. Two kinds: public (resolved on the internet) and private (resolved only from VPCs you associate with it). The price of a hosted zone is $0.50/month, plus per-query charges (~$0.40 per million for the first billion).

A record set is the actual DNS data — type (A, AAAA, CNAME, MX, TXT, ...), name, TTL, value. Route 53's signature feature is the alias record: a synthetic A/AAAA record that points to an AWS resource (ALB, CloudFront, S3 website endpoint, API Gateway) by ARN instead of by IP. Alias records are free to query (no DNS-query charge), evaluate the target's health automatically, and resolve to whatever IPs AWS is using today.

Alias records over CNAME — always. CNAMEs can't be set at the zone apex (example.com bare), and they cost per-query. Alias records work at the apex, cost nothing to resolve, and follow target changes automatically. Use alias for any record pointing at an AWS resource. The "apex" rule isn't a Route 53 quirk — it's RFC 1912 — CNAMEs can't coexist with other records at the same name, and the apex must have SOA/NS records. Alias sidesteps this by being a synthetic record type that resolves like an A record.

5 · The seven routing policies

PolicyWhat it doesConcrete use case
SimpleOne record, one answer.Single endpoint. The 90% case — app.example.com → ALB DNS.
WeightedMultiple records with weights; Route 53 picks proportionally.Canary deploys (10% to v2 ALB, 90% to v1); A/B testing; gradual region migration.
LatencyPick the record whose AWS region has the lowest measured latency to the resolver.Active-active multi-region; us-east-1 and eu-west-1 each have their own ALB, route to nearest.
FailoverPrimary record; if its health check fails, switch to secondary.Active-passive DR; primary in us-east-1, static-site fallback in S3 if the primary is down.
GeolocationMatch client's country/continent; serve a specific record.Data-residency compliance (EU users hit eu-* infra); content geo-blocking; language-specific landing pages.
GeoproximityDistance-based with optional bias; needs Route 53 Traffic Flow.Smoothly shift % of traffic across regions as you scale a new region up or down.
Multivalue answerUp to 8 healthy answers shuffled, with health-check gating."Poor man's load balancing" — many backend IPs, client picks one. Less than an ALB; more than DNS round-robin.

You can nest policies — a top-level geolocation record can have failover children inside each region, etc. Most multi-region production setups use Latency for steering with Failover wired into the health checks underneath. Traffic Flow (a separate, paid Route 53 product) gives you a visual editor for the resulting policy tree.

6 · How latency-based routing decides

Latency routing doesn't measure each client's latency live. It uses AWS's internal latency dataset — measurements AWS continuously takes between every region and every recursive resolver IP it observes — to decide which region is "fastest" for the resolver issuing the query. When you create latency records in us-east-1 and eu-west-1 for the same name, Route 53 answers each query with the IP whose region has the lowest measured RTT to the resolver.

This is approximate. The decision is per-resolver, not per-client; a corporate user in Berlin going through a US-based corporate proxy will be routed to us-east-1 because that's where the resolver lives. Mobile clients using carrier resolvers usually work as intended because the resolver follows the device. EDNS Client Subnet (ECS) partially fixes the proxy problem — when supported, the recursive resolver passes a /24-ish hint of the client's subnet to the authoritative server, which can refine the decision. Route 53 supports ECS for geolocation and latency policies; not every recursive resolver sends it.

The result: latency routing is accurate enough for the "route this user to the closest region" use case, but not precise enough to use as a primary fairness mechanism. If exact regional distribution matters (compliance, cost), use weighted with explicit percentages.

7 · Health checks and the failover timeline

A Route 53 health check probes an endpoint from multiple global locations and aggregates the result. Three types:

  • Endpoint health check. HTTP/HTTPS/TCP probe to an IP or DNS name. Used to gate failover and latency routing.
  • Calculated health check. Boolean combination of other health checks ("healthy iff at least 2 of these 4 are healthy"). Used to model app-level health from multiple component probes.
  • CloudWatch alarm health check. Use an existing CloudWatch alarm (e.g., "p99 latency > 500ms"). Anything CloudWatch can alarm on can drive DNS failover.

The Route 53 health-checker fleet runs from 50+ geographically distributed locations (the AWS health-checker IPs are publicly published so you can allow them through your firewalls). Each checker probes independently; "unhealthy" means a configurable threshold of them have failed in a configurable window.

Failover speed is bounded by TTL. Route 53 detects the failure within ~30 seconds with default settings; with fast (10s) intervals plus FailureThreshold = 1, you can pull that to ~10s. But clients cache the old DNS answer for the record's TTL — typically 60 s in production. Worst case, failover takes ~90 s end-to-end, plus however long the slowest browser holds onto the response. Setting TTL = 60 is the conventional production choice; lower than 30 makes the query bill spike since recursive resolvers re-query more often.

8 · Private hosted zones — service discovery

Private hosted zones resolve only from VPCs you explicitly associate with them. The pattern: register internal service names like users.internal.example.com against private ALBs, NLBs, or RDS endpoints. Apps inside the VPC look them up like any DNS; nothing leaks externally.

This is also how AWS Cloud Map / ECS Service Discovery works under the hood — each ECS task in a service is registered as a record in a private zone, with Route 53 maintaining the membership as tasks come and go. EKS has a parallel mechanism via the Kubernetes DNS and ExternalDNS controller.

9 · Real-world case studies

Three public stories give a sense of how Route 53 shapes systems at scale.

Netflix — regional failover and chaos testing. Netflix runs active-active across multiple AWS regions and uses Route 53 latency policies plus health checks as the steering layer. Their Tech Blog post on active-active resiliency describes how a region's "evacuation" — pulling all traffic out of, say, us-east-1 during a regional incident or planned chaos test — is essentially a controlled Route 53 health-check flip. The "Kong" health check goes red, Route 53 stops returning that region's IP, traffic drains to the other regions over ~minutes (TTL plus connection draining). They've used the same machinery in chaos engineering drills, deliberately failing a region to verify the rest can absorb the load. The interesting design choice: Netflix treats DNS failover as the coarse mechanism (which region) and Eureka/service discovery as the fine one (which instance within a region).

Cloudflare — analysing Route 53. Cloudflare runs their own competing authoritative DNS (1.1.1.1 is the recursive resolver; their authoritative DNS is a separate product) and have a tradition of writing detailed analyses of competitors. Their posts on Route 53 generally praise the architectural choices — anycast plus shuffle sharding plus the 100% SLA — while observing the trade-offs: Route 53 is operationally closer to "DNS as a database with policies" than to "DNS as code." Their critique, which is useful to internalise: the routing-policy abstractions can express complex failover, but the deployment story (Terraform / CDK as source-of-truth) is mostly the customer's problem; misconfigurations are easy and not always visible until they hurt.

Slack — DNS-driven blue/green at scale. Slack has written about their deployment strategy on the engineering blog; one recurring theme is using DNS-layer weighted routing to gradually shift traffic between blue and green pools. Each deploy ramps a small fraction (1%, 10%, 50%, 100%) over a window long enough to spot regressions in metrics — far longer than a load-balancer cutover, but with the advantage that they can hold at intermediate weights as long as they want. The trade-off, which they discuss honestly, is that DNS-layer ramps are coarse (you can't pick which 1% — it's whoever's resolver re-queries first) and slow (TTL-bounded), but they cleanly cross load-balancer and even region boundaries. The complementary pattern is fine-grained header-routed canaries at the ALB layer for the last mile.

The through-line: Route 53 is most useful as the outermost traffic-steering layer — region selection, failover, gross-grained percentage splits — with finer-grained routing handled by load balancers and service meshes underneath. Treating DNS as a fine-grained request router is reliably disappointing.

10 · Build it yourself — weighted blue/green

Simulate a canary deploy: two ALBs (or simulate with two IPs), 90% traffic to blue, 10% to green, then flip.

  1. Create a public hosted zone (uses a dummy domain — replace with one you own to actually resolve externally).
    ZONE_ID=$(aws route53 create-hosted-zone --name lab.example.com \ --caller-reference $(date +%s) \ --query 'HostedZone.Id' --output text | sed 's|/hostedzone/||')
  2. Create two weighted A records pointing at different IPs.
    cat > /tmp/blue.json <<'EOF' { "Changes": [{ "Action": "CREATE", "ResourceRecordSet": { "Name": "app.lab.example.com", "Type": "A", "TTL": 60, "SetIdentifier": "blue", "Weight": 90, "ResourceRecords": [{ "Value": "203.0.113.10" }] }}]} EOF aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file:///tmp/blue.json cat > /tmp/green.json <<'EOF' { "Changes": [{ "Action": "CREATE", "ResourceRecordSet": { "Name": "app.lab.example.com", "Type": "A", "TTL": 60, "SetIdentifier": "green", "Weight": 10, "ResourceRecords": [{ "Value": "203.0.113.20" }] }}]} EOF aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file:///tmp/green.json
  3. Flip the weights (90:10 → 50:50 → 0:100) by repeating UPSERT with new weights.
    # Use 'UPSERT' instead of 'CREATE' in the JSON for each weight change. # In practice: a deploy pipeline calls this with weights 90/10 → 50/50 → 0/100 over 30 minutes.
  4. Add a health check tied to the green record.
    HC=$(aws route53 create-health-check --caller-reference $(date +%s) \ --health-check-config '{"IPAddress":"203.0.113.20","Port":443,"Type":"HTTPS","ResourcePath":"/health","FullyQualifiedDomainName":"app.lab.example.com","RequestInterval":30,"FailureThreshold":3}' \ --query 'HealthCheck.Id' --output text) # Update the green record with HealthCheckId = $HC — if /health fails, Route 53 stops returning it.
  5. Tear down.
    aws route53 delete-health-check --health-check-id $HC # Then change-resource-record-sets with Action DELETE for each record. aws route53 delete-hosted-zone --id $ZONE_ID

11 · What breaks

  • TTL too high. Failover takes minutes because clients are still resolving the stale IP. Set TTL to 60 s for anything that might need to fail over. Default with the Route 53 console (300s) is fine for static records, painful for failover targets.
  • Health-check thresholds add up to slow detection. Default health-check config is 30s interval × FailureThreshold 3 = 90 seconds minimum from failure to "unhealthy." Even with fast checks (10s × 1 fail = 10s) you're still bounded by resolver TTL on top. Total realistic failover for an end user is 30s–3min depending on settings.
  • Resolver caching ignores your TTL. Public recursive resolvers commonly cap effective TTLs to 30–60s regardless of what your zone says. Mobile carriers and corporate proxies sometimes do worse. Don't promise sub-30s failover end-to-end.
  • Geolocation routing for VPN users. Route 53 matches against the resolver IP, not the client. A US user on a Tokyo VPN looks like Japan; an EU user behind a US-based corporate proxy looks like the US. For data-residency compliance this can be a real problem — you may be routing the right country's traffic to the wrong region. Pair with application-layer geolocation if it matters.
  • Health check from us-east-1 only. Default health checkers come from multiple regions; if you accidentally restrict to one, a regional Route 53 outage will incorrectly fail your endpoints.
  • Negative caching. If a zone returns NXDOMAIN, resolvers cache that for the zone's SOA negative TTL. New records added after a failed lookup may take minutes to be visible.
  • Query bill spikes. Standard queries $0.40/million; latency-based and geo queries $0.60/million. A high-traffic public DNS can run hundreds of millions of queries/day. Alias records skip the query charge.
  • You can't CNAME the apex. RFC-mandated; CNAMEs can't coexist with the apex's SOA/NS. The Route 53 alias record sidesteps this; outside Route 53, you need an A record at the apex pointing at literal IPs (and now you're tracking ALB IPs by hand).
  • Geo policy with no default. If a client's country doesn't match any rule and there's no default, Route 53 returns NoAnswer. Always set a catchall.

12 · Further reading

Found this useful?