---
title: "07 — Route 53: DNS Plus Traffic Steering in One Service"
uid: route53-dns
tags: ["dns", "health-checks", "aws", "routing-policy", "hosted-zones", "roadmap:aws", "route53"]
excerpt: "Route 53 is DNS plus something DNS alone doesn't do: routing policies that turn answers into traffic-steering decisions, with health checks failing over automatically."
date: 2026-08-13T03:28:30+0000
source: https://www.aveshina.my.id/en/blog/route53-dns
---

"Just DNS, the thing that points a name at an IP" made Route 53 sound boring — and I was missing the half that isn't boring. The shape that landed: **Route 53 is a managed DNS service whose records live in hosted zones, and whose real power is a set of routing policies that turn the DNS answer into a traffic-steering decision, with health checks that fail over without me touching anything** [1]. The "53" is the port DNS speaks. Once I saw routing policies and health checks as the part that's *more than DNS*, the service stopped being boring.

## Hosted zones: the container for records

A **hosted zone** is a container for the DNS records of one domain — example.com, say [2]. When I create one, Route 53 assigns it a set of name servers and an SOA record; I then point my registrar at those name servers so Route 53 becomes authoritative for the domain.

Inside a hosted zone I create **records**, each mapping a name and type to a value:

- **A** — name to IPv4 address.
- **AAAA** — name to IPv6 address.
- **CNAME** — name to another name (an alias).
- **MX** — mail exchange.
- **TXT** — arbitrary text (used for verification, SPF, DKIM).

The non-obvious AWS-specific record type is the **Alias record**: it points at an AWS resource (a load balancer, a CloudFront distribution, an S3 bucket website) and Route 53 tracks the resource's changing IPs internally, for free. For anything that resolves to an AWS resource, Alias beats CNAME.

## Routing policies: the traffic-steering layer

This is the part that's *more than DNS*. A routing policy decides which answer Route 53 returns when there are multiple candidates, and the choice reshapes the traffic [3]:

- **Simple** — one answer. The default; for a single resource.
- **Weighted** — split traffic by percentage across multiple resources. "10% to the new version, 90% to the old." Canary releases without a load balancer.
- **Latency** — return the answer with the lowest network latency to the caller. Spins up the same app in multiple regions and lets DNS send each user to the closest one.
- **Failover** — active/passive. Serve the primary; if its health check fails, serve the backup. DNS-level disaster recovery.
- **Geolocation** — answer based on where the user *is*. "EU users get the EU endpoint" for data residency.
- **Geoproximity** — answer based on where my *resources* are, with optional bias to shift traffic between regions.
- **Multivalue answer** — return up to eight healthy records, randomly ordered. A poor-person's load balancer at the DNS layer.

The shift in my head: DNS is no longer "one name, one IP." With the right policy, the same name returns different answers to different callers, or changes its answer when something breaks.

## Health checks: the failover engine

**Health checks** are how Route 53 knows a resource is down [4]. I point a health check at an endpoint (an HTTP URL, a TCP port, another health check, or a CloudWatch alarm); Route 53 polls it from globally distributed locations at an interval I choose. If it fails, the health check goes "unhealthy," and any failover or multivalue record associated with it stops returning that endpoint.

The pattern this enables is **DNS-level failover**: I stand up my app in two regions, create two records under the same name (primary + secondary) with a failover routing policy, attach a health check to the primary, and Route 53 serves the primary while it's healthy and automatically flips to the secondary when it isn't. No load balancer, no manual DNS edit. The trade-off worth remembering: DNS answers are cached (by resolvers and by clients) according to the record's **TTL**, so failover is not instant — a low TTL (60s) makes failover faster but increases query volume and cost.

```figure
<svg viewBox="0 0 680 240" xmlns="http://www.w3.org/2000/svg" class="my-6 w-full max-w-2xl" role="img" aria-label="Route 53 routing a user's DNS query under a failover policy. A user asks for app.example.com. Route 53 checks a health check on the primary endpoint. Healthy = answer the primary ALB. Unhealthy = answer the secondary ALB in another region. A TTL clock sits beside the records, noting that resolvers cache the answer for the TTL duration.">
  <g font-family="ui-sans-serif, system-ui, sans-serif" text-rendering="geometricPrecision">
    <defs><marker id="r5a" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#64748b"/></marker></defs>

    <!-- user -->
    <rect x="30" y="100" width="90" height="40" rx="8" fill="#e0e7ff" stroke="#6366f1"/><text x="75" y="124" font-size="11" font-weight="700" fill="#1e1b4b" text-anchor="middle">user</text>
    <path d="M120,120 L210,120" stroke="#64748b" stroke-width="1.5" marker-end="url(#r5a)"/>
    <text x="165" y="113" font-size="9" fill="#475569" text-anchor="middle">app.example.com?</text>

    <!-- Route 53 -->
    <rect x="210" y="90" width="140" height="60" rx="8" fill="#fce7f3" stroke="#db2777"/>
    <text x="280" y="115" font-size="11" font-weight="700" fill="#500724" text-anchor="middle">Route 53</text>
    <text x="280" y="132" font-size="9" fill="#500724" text-anchor="middle">failover policy</text>

    <!-- health check -->
    <rect x="210" y="170" width="140" height="40" rx="6" fill="#dcfce7" stroke="#16a34a"/>
    <text x="280" y="187" font-size="10" font-weight="700" fill="#052e16" text-anchor="middle">health check</text>
    <text x="280" y="201" font-size="9" fill="#052e16" text-anchor="middle">polls primary every 30s</text>
    <line x1="280" y1="150" x2="280" y2="170" stroke="#64748b" stroke-width="1.2" marker-end="url(#r5a)"/>

    <!-- primary -->
    <rect x="430" y="60" width="200" height="50" rx="8" fill="#dcfce7" stroke="#16a34a"/>
    <text x="530" y="80" font-size="11" font-weight="700" fill="#052e16" text-anchor="middle">Primary ALB (region A)</text>
    <text x="530" y="97" font-size="9" fill="#052e16" text-anchor="middle">served when healthy</text>
    <path d="M350,110 L430,85" stroke="#16a34a" stroke-width="1.5" marker-end="url(#r5a)"/>

    <!-- secondary -->
    <rect x="430" y="140" width="200" height="50" rx="8" fill="#fee2e2" stroke="#dc2626"/>
    <text x="530" y="160" font-size="11" font-weight="700" fill="#7f1d1d" text-anchor="middle">Secondary ALB (region B)</text>
    <text x="530" y="177" font-size="9" fill="#7f1d1d" text-anchor="middle">served when primary is down</text>
    <path d="M350,135 L430,165" stroke="#dc2626" stroke-width="1.5" stroke-dasharray="4 3" marker-end="url(#r5a)"/>

    <!-- TTL note -->
    <text x="530" y="215" font-size="9" font-style="italic" fill="#64748b" text-anchor="middle">TTL gates how fast failover propagates</text>
  </g>
</svg>
```

The whole failover loop is DNS + health check + TTL, and the only moving part I own is wiring them together.

## How I use this

Route 53 is the front door of almost every AWS-hosted app I run. My standing setup: a hosted zone per domain, an Alias record from the apex (example.com) straight to the load balancer (which CNAME cannot do for a zone apex — Alias can), and a TTL low enough to make any future change bearable (60–300s). Weighted routing is my cheapest canary-deploy tool — I shift 5% of DNS answers to a new stack and watch the metrics before going further. Failover across regions is the disaster-recovery pattern I document but hope never to need, and I keep the TTL short on those records so the flip actually reaches users in minutes rather than hours. DNS is rarely the exciting part, but getting it right is what makes the rest of the stack reachable.

## References

[1] Amazon Web Services, "What is Amazon Route 53," 2024. [Online]. Available: [https://aws.amazon.com/route53/](https://aws.amazon.com/route53/)

[2] Amazon Web Services, "Working with hosted zones," Route 53 Developer Guide, 2024. [Online]. Available: [https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-working-with.html](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-working-with.html)

[3] Amazon Web Services, "Choosing a routing policy," Route 53 Developer Guide, 2024. [Online]. Available: [https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html)

[4] Amazon Web Services, "Route 53 health checks," Route 53 Developer Guide, 2024. [Online]. Available: [https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/welcome-health-checks.html](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/welcome-health-checks.html)

```quiz
Q: A Route 53 Alias record is preferable to a CNAME for pointing at an AWS load balancer because…
- Alias tracks the resource's changing IPs for free and works for the zone apex
- Alias is faster to type
correct: 0
explain: Alias records point at AWS resources and follow their underlying IPs at no cost. Unlike CNAME, Alias can also be used at the zone apex (e.g. example.com).

Q: Which routing policy sends each user to the endpoint with the lowest network latency to them?
- Weighted
- Latency
correct: 1
explain: Latency routing returns the answer with the lowest latency to the caller — the basis for multi-region active-active setups.

Q: You want a canary deploy that sends 5% of traffic to a new stack via DNS only. Use…
- Weighted routing policy
- Simple routing policy
correct: 0
explain: Weighted splits answers by percentage across multiple targets. Point 5% at the new stack and 95% at the old.

Q: In a failover setup, what actually causes Route 53 to stop serving the primary record?
- The primary's health check goes unhealthy
- The TTL reaches zero
correct: 0
explain: Route 53 polls the endpoint via a health check. When it fails, the record is pulled from answers. TTL only governs how quickly resolvers notice the change.

Q: Why is a short TTL (e.g. 60s) used on failover records?
- It makes failover propagate faster to resolvers, at the cost of more query volume
- It reduces Route 53's price per query
correct: 0
explain: Resolvers cache answers for the TTL. A shorter TTL means a failed-over answer reaches users sooner, but increases query count and cost.
```
