14 — CloudFront: Putting My Content Closer to the User
"A CDN, like any other" was how I filed CloudFront, which meant I had no vocabulary for the levers it actually exposes. The controls that registered: CloudFront is a global cache that sits in front of my origin (an S3 bucket, an ALB, any HTTP endpoint) and serves requests from whichever edge location is closest to the user, and the operational art is three controls — distributions (the cache's shape), policies (what defines the cache key and who can access what), and invalidations (forcing the cache to forget) [1]. Once those three were distinct, the CDN stopped being a black box.
The core trick: edge locations
CloudFront's network is a fleet of edge locations — small Points of Presence spread across the world, far more numerous than AWS regions. When a user requests a file, the request lands at the nearest edge location. If that edge has the file cached (a cache hit), it returns immediately — fast, because the bytes come from nearby. If it doesn't (a cache miss), CloudFront fetches from the origin I configured, returns the file to the user, and keeps a copy at the edge so the next request is a hit.
The win is twofold: latency drops because the user gets bytes from a nearby edge instead of a single distant origin, and origin load drops because most requests never reach it. The same pattern every cache uses; the special part is the global edge footprint.
Distributions: the cache's shape
A distribution is the CloudFront configuration unit — it tells CloudFront what to serve and where to get it [2]. Two flavors:
- Web distribution — for websites, APIs, static assets. The default; almost everything is this.
- RTMP distribution — for legacy media streaming. Largely historical.
A web distribution binds together: one or more origins (the S3 bucket, the ALB), behaviors (rules mapping URL paths to origins and to cache settings), and the global settings (price class, TLS certificate, alternate domain names). The way of thinking: a distribution is a routing-and-caching configuration that points at my real backend.
Cache policies: the cache key
The single most important CloudFront concept is the cache key — the set of inputs that determines whether two requests are treated as the same cached object. If the key includes only the URL, then /image.jpg is cached once for everyone. If the key also includes a header or a query string, those become part of the lookup.
Cache policies (and origin request policies) are AWS's structured way of controlling this [3]:
- Cache policy — what goes into the cache key. Tighten it (URL only) to maximize hit ratio; widen it (include device header, query string) to vary the cached response.
- Origin request policy — what gets forwarded to the origin on a miss. Even when the cache key is tight, I might want the origin to see a header for analytics or auth.
The classic mistake: putting too much in the cache key, which fragments the cache and tanks the hit ratio. The discipline is to include only what actually changes the response — usually the URL, sometimes a Cookie or Accept-Language, rarely more.
Access control: who can reach what
CloudFront layers access control on top of caching [3]:
- Origin Access Control (OAC) — for S3 origins, makes the bucket private and lets only CloudFront read from it. Users can never bypass CloudFront to hit the bucket directly.
- Signed URLs / signed cookies — for premium content. CloudFront signs a time-limited token so only authorized users fetch certain paths.
- AWS WAF + geo restrictions — a web application firewall and country-level allow/deny lists at the edge.
The pattern: keep the origin (S3, ALB) private to CloudFront, and do all access decisions at the edge. That way the cache is also a security boundary.
Invalidations: forcing the cache to forget
CloudFront caches objects until their TTL expires. If I deploy a new version of app.js before the TTL, the edges keep serving the old one — that's the cache doing its job, but it's also a problem. An invalidation tells CloudFront to drop specific paths from its edge caches immediately, forcing the next request to re-fetch from origin [4].
aws cloudfront create-invalidation --distribution-id ABCD1234XYZ --paths "/app.js" "/assets/*"The cost trade-off: invalidations are billable after a free monthly allowance, and broad invalidations (/*) can be expensive and hammer the origin. The better pattern is content-addressed filenames — app.<hash>.js — so a new deploy is a new path the cache has never seen, and the old path simply expires. Invalidations are the fallback for when I can't change the filename.
How I use this
CloudFront is the front door for almost everything I serve to users — static assets, single-page apps, even APIs where caching is sane. My standing setup: an S3 origin for static assets with OAC so the bucket is private to CloudFront; content-addressed filenames so deploys never need invalidations; a tight cache policy (URL-only key for static, carefully widened for APIs) to keep the hit ratio high; and the TLS certificate on the distribution so the whole thing is HTTPS. For dynamic APIs I use CloudFront more for its edge-to-origin network path and WAF than for caching, with cache policies that pass everything through. The mental test for any CloudFront change is the same as for any cache: what does the cache key include, and what happens when the cached thing changes? Answering those two up front prevents most of the cache-related incidents I've ever caused.
References
[1] Amazon Web Services, "What is Amazon CloudFront?," 2024. [Online]. Available: https://aws.amazon.com/cloudfront/
[2] Amazon Web Services, "Working with distributions," CloudFront Developer Guide, 2024. [Online]. Available: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-working-with.html
[3] Amazon Web Services, "Security and IAM in CloudFront," CloudFront Developer Guide, 2024. [Online]. Available: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/security-iam.html
[4] Amazon Web Services, "Invalidating files," CloudFront Developer Guide, 2024. [Online]. Available: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html
Knowledge check · Question 1 of 5
What does a CloudFront cache HIT mean?
Comments
Leave a Comment
You must be signed in to comment
0 Comments
No comments yet. Be the first to comment!