R53
Amazon Route 53 Amazon CloudFront

How a request
finds you

You type a domain and the page is there before you finish blinking. Twenty-six stops on what happens in between — and at the end, proof that this deck itself made the trip.

Three questions, in order

Every page load answers them one after another. Lose any one and nothing loads.

1 — Where is it? Turn a name into an address. Route 53 answers, and decides which address you get. 2 — Who serves it? That address belongs to an edge location near you, not a server in one distant region. 3 — Where are the bytes? Asked only if the edge doesn't already have them. Most of the time, it does. stops 3–11 stops 12–24 stops 25–26

Nobody knows the whole answer

DNS is a chain of referrals. Each server knows only who to ask next, until one is authoritative for the name.

Browser asks once Resolver does the legwork Root ask .com .com ask Route 53 Route 53 authoritative — answers one answer comes back Every hop is cached, so the next person on your network skips nearly all of it.

Route 53 does three separate jobs

Billed separately, configured separately, and conflated constantly.

Sells you the name

Domain registration. The only part you could buy elsewhere and still use everything below.

Answers for the name

Authoritative DNS. A hosted zone holds your records, and four assigned name servers serve them worldwide.

Watches your endpoints

Health checks. Route 53 is the rare DNS service that changes its answers based on whether a target is still alive.

That third job is the interesting one. It turns DNS from a lookup table into a control plane, which is what makes failover and latency routing possible at all.

Registrar and DNS are two different jobs

The domain is registered at Hostinger. The records will live in Route 53. You delegate, rather than transfer.

Hostinger registrar — owns the billing .cloud registry publishes your NS Route 53 hosted zone authoritative — answers paste four name servers resolvers follow them Create the zone first, copy its NS values into Hostinger's name server field, then wait for the old TTL to expire.

Public hosted zone

Answers anyone on the internet. This is what asimisinthe.cloud needs.

Private hosted zone

Answers only from inside the VPCs you associate with it. Same records, invisible from outside.

A hosted zone is just a file

Records map a name to a value, plus a type telling the resolver how to read that value.

; the four servers that answer for you NS asimisinthe.cloud ns-1042.awsdns-02.org ; a name pointing at an IPv4 address A api.asimisinthe.cloud 54.221.10.4 ; a name pointing at another name CNAME www.asimisinthe.cloud asimisinthe.cloud ; AWS only — a name pointing at an AWS target ALIAS asimisinthe.cloud d1x2y3.cloudfront.net

NS and SOA arrive with the zone

Delete them and the zone stops answering. A surprisingly common self-inflicted outage.

Type decides where the lookup ends

A and AAAA finish with an address. CNAME and ALIAS send the resolver on one more hop.

TTL is how long you lose control

Resolvers cache your answer for exactly as long as you told them to. Nothing you change at AWS shortens that.

first query the full walk — root, .com, Route 53 second query, inside the TTL resolver cache Nothing left the building.

Long TTL is fast and cheap. Short TTL is agile. Before a planned cutover, drop the TTL to 60 seconds a day ahead, migrate, then put it back.

The reason this deck needs Alias

A CNAME cannot exist at the root of a domain. The spec forbids it, and the root is exactly where you want your site.

CNAME at the apex — rejected

asimisinthe.cloud → d1x2y3.cloudfront.net

The apex already holds NS and SOA records. A CNAME has to be the only record at its name, so the two can't coexist. Route 53 refuses to save it.

Alias at the apex — works

asimisinthe.cloud ⇒ d1x2y3.cloudfront.net

Alias is Route 53's own extension. It resolves the target internally and hands back plain A records, so the apex never sees a CNAME. Free to query, and it follows the target's IPs as they change.

Alias only points at AWS targets — CloudFront, ALB, S3 website endpoints, or another record in the same zone. For anything else you still need a CNAME on a subdomain.

One name, many answers

A routing policy decides which record Route 53 hands back. Same question, different answer depending on who is asking. Try them.

us-east-1idle eu-west-1idle ap-south-1idle viewer in Ohio viewer in Dublin viewer in Karachi

One record, one answer, for everyone. No health awareness and no geography — the default, and still the right choice most of the time.

Four more, by intent

The rest differ in what they optimise for, not in how they work.

Geolocation

Answers by where the viewer is — continent, country, or US state. For language, licensing and legal boundaries. Always set a default record, or viewers you didn't anticipate get nothing at all.

Geoproximity

Answers by distance to your resources, with a bias dial that grows or shrinks a region's catchment area. The only policy that needs traffic flow to configure.

Multi-value

Returns up to eight healthy records at once and lets the client choose. Health-aware round robin — not a load balancer, but far better than nothing.

IP-based

Answers by the viewer's CIDR block. For when you know a particular ISP's users should land somewhere particular.

The distinction people miss: latency optimises for speed and will happily send a Dublin viewer to Virginia if that path is faster today. Geolocation optimises for location and never will.

Failover needs someone watching

Health checkers around the world request your endpoint on a schedule. Fail enough of them and Route 53 stops handing out that record.

viewer primary — healthy us-east-1 standby — idle eu-west-1 Health checkers ~15 locations, every 30 seconds 18 of 18 reporting healthy

A health check can watch an endpoint, watch other health checks, or watch a CloudWatch alarm. Only the first one costs you an HTTP request.

Amazon CloudFront

Distance is the slowest part of your stack

You can take a query from 40 ms to 4 ms. You cannot negotiate with the speed of light between Karachi and Virginia.

Karachi to Virginia, direct roughly 12,000 km — about 230 ms round trip on a good day Karachi to the nearest edge The same bytes, one-tenth the wait, because they never crossed an ocean.

A CDN does not make your origin faster. It moves the origin out of the request's way — which turns out to be the same thing.

What a distribution actually is

A global fleet of caches, plus rules describing where to fetch from and what to keep.

viewer Edge location 700+ worldwide Regional cache bigger, fewer, warmer Origin S3 or ALB every hop to the right of the edge is one you are trying to avoid

The regional layer is why a cold edge is rarely as slow as it sounds. A miss usually resolves one hop away rather than all the way home.

A cache hit never reaches your origin

The same request, measured two ways.

viewer Edge hit 12 ms miss Edge S3 origin 210 ms

The cache key decides everything

CloudFront hashes parts of the request into a key. Add a part and you split the cache — every extra value is another copy to fill and another miss to pay for.

asimisinthe.cloud/index.html

Objects now cached

1

One object, shared by every viewer on earth. This is the hit rate you want.

The rule

Include something in the key only if the response genuinely changes because of it. A cookie your origin ignores turns one cached object into one object per user, and your hit rate into a rounding error.

Two policies, one shared vocabulary

A cache policy chooses what goes into the cache key — and those parts get forwarded too. An origin request policy forwards things without putting them in the key. That difference is the whole point of having two.

Cache policy
Origin request policy
Query strings
none · whitelist · allExcept · all
none · whitelist · allExcept · all
Cookies
none · whitelist · allExcept · all
none · whitelist · allExcept · all
Headers
none · whitelist  — only these two
none · whitelist · allExcept ·
allViewer · allViewerAndWhitelistCloudFront

Why headers have no "all" in a cache policy

Putting every viewer header in the key would give almost every request its own object — User-Agent alone would shatter it. AWS removed the foot-gun: forward all headers with an origin request policy instead, and keep them out of the key.

The pattern you'll actually use

Cache policy keeps the key narrow. Origin request policy hands the origin what it needs to do its job — CloudFront-Viewer-Country, User-Agent, an auth cookie — none of which should split the cache.

Four filters, one grammar

Query strings, cookies and headers each take the same four settings, in both policies. Most of debugging a bad hit rate is working out which one you picked.

None

Strips them out. Nothing reaches the key, nothing reaches the origin. The default, and exactly right for a static site that ignores them anyway.

Whitelist

Name the items that may pass; everything else is dropped. The console calls it include specified. Reach for this one first — it is the only option whose blast radius you can see.

AllExcept

Everything passes but the ones you name. Its real use is dropping the noise — utm_source and friends, which never change the response but would each fork the cache.

All

Everything passes. In a cache policy that is a key per unique combination, which is defensible only for a path you have already decided not to cache.

The same four words carry a different consequence in each policy. In a cache policy the choice sets your hit rate. In an origin request policy it only sets how much your origin gets told — costly to your backend, free to your cache.

Two ways to stop serving stale bytes

Wait for the TTL, or force the issue. One is free and slow; the other is immediate and metered.

6 edges holding v1
Los Angeles Singapore

Let the TTL expire

The origin's Cache-Control header sets it; the cache policy's min, default and max TTL clamp it. Costs nothing, but you wait.

Invalidate the path

Evicts matching objects from every edge within minutes. A generous number of paths are free each month, and billed after that — so version your filenames instead of invalidating on every deploy.

One distribution, different rules per path

Cache behaviours match the URL path and decide the origin, the cache policy, the allowed methods, and whether the response is cached at all.

Distribution /api/* ALB origin, caching disabled, all HTTP methods allowed /static/* S3 origin, one-year TTL, GET and HEAD only Default (*) S3 origin, the catch-all — always evaluated last

Precedence is by the order you list them, not by specificity. Put a broad pattern above a narrow one and the narrow one never runs.

Lock the origin so only the edge can reach it

A public bucket behind a CDN is still a public bucket. Origin access control signs CloudFront's requests so the bucket can refuse everyone else.

viewer CloudFront signs with OAC Private S3 bucket block all public access anyone else 403 — the bucket policy names one principal

The same distribution can hold an ALB or EC2 origin alongside it, where CloudFront gives you TLS termination, header manipulation and shielding rather than caching. Shutting that door works nothing like this one.

When the origin is compute, not a bucket

A bucket has OAC. An ALB or an EC2 instance has a security group — which for years meant the origin had to sit on the public internet and hope the allowlist held.

The classic way — the origin is public, the security group is the door CloudFront internet Public ALB or EC2, public subnet SG allows CloudFront's managed prefix list Private EC2 targets SG allows only the ALB's security group VPC origins — the request never touches the internet CloudFront private VPC origin an endpoint AWS manages inside your VPC Private ALB, NLB or EC2 private subnet, no public IP at all

The question to ask of any origin is simply whether it is reachable without CloudFront. A public ALB is — the prefix list narrows the crowd but the door still faces the street. A VPC origin has no door on that side of the building, which is what OAC does for a bucket.

Controlling who gets what

Three levers, three different questions

Geo restriction

Allow or block whole countries at the edge, using CloudFront's own GeoIP lookup. The request is refused before it reaches your origin. For licensing and compliance, not for security.

Signed URLs

One signed link per file, carrying an expiry and optionally an IP range. Right for a single download — a purchased video, a report, a firmware image.

Signed cookies

One signature covering many files. Right for a whole library behind a paywall, where minting a URL per asset would be absurd.

Both signature types verify against a key group — public keys you upload to CloudFront, with the private key held by whatever service issues the signatures. The root account key pair is the legacy path and no longer the recommended one.

Who holds which key

Signing and verifying happen in two different places, run by two different parties, at two different times. Almost every mistake here is a confusion about which is which.

Issuing — on your server, once per user viewer Your backend private key — never leaves this box signature The viewer now holds a signed URL or cookie carrying an expiry, and optionally an IP range Redeeming — at the edge, on every single request viewer CloudFront public key in a key group — checks the math Origin serves the object a bad signature never gets this far

CloudFront never learns who your subscribers are, and your database is never consulted at request time. The signature is the whole handoff between the two.

Two signatures that sound alike and aren't

Both hand someone a temporary link. They are signed by different things, land in different places, and can do different amounts of damage.

CloudFront signed URL

Signed by a private key whose public half sits in a key group. Verified at the edge, so the object stays cached and still arrives from the nearest location.

Can front any origin, not only S3. Read access only. The policy can pin an expiry, a start time, and a source IP range.

S3 pre-signed URL

Signed by the IAM credentials of whoever generated it, and inherits exactly that identity's permissions — which is the part that surprises people.

Points straight at the bucket, bypassing the edge entirely. Can grant writes as well as reads, so a leaked one may let a stranger upload.

If the content is meant to be distributed, sign it at CloudFront. A pre-signed URL in front of a private bucket you have already locked with OAC will simply be refused — the two mechanisms are answering different questions.

Putting it together

Every piece, one request

viewer Route 53 alias at the apex health checks decide which record is returned CloudFront edge TLS, cache key, behaviours, geo rules, signatures ACM certificate must live in us-east-1 S3 private, OAC only this half runs only on a miss

You have been looking at it for twenty minutes

This deck is a static site in S3, private, served through CloudFront, reached by an alias record at the apex. Open the network tab.

$ dig +short asimisinthe.cloud 18.164.52.31 ← CloudFront, not S3 $ curl -sI https://asimisinthe.cloud | grep -i x-cache x-cache: Hit from cloudfront $ curl -sI https://asimisinthe-deck.s3.amazonaws.com/index.html HTTP/1.1 403 Forbidden ← OAC working

Then: edit one word, aws s3 sync, reload — still the old copy. Invalidate, reload — new copy, and the header flips back to a miss.

Three things that will bite you

The certificate must be in us-east-1. CloudFront reads ACM only from that region, no matter where anything else lives.

Use alias, not CNAME, at the apex. The subdomain works either way, which is why people only discover this at the root.

Distributions deploy slowly. Certificate validation and propagation take real minutes — never do them live in front of an audience.

Presenting
→ or Space next    ← back    R replay this slide
Home first    End last    click any stop on the left rail to jump
? close