Course outline

11.1

CloudFront: Caching at the Edge

Edge locations, origins, Origin Access Control, cache keys and TTL, and CloudFront vs S3 replication.

26 min Reading + animations

Tip: tap or hover any dotted-underlined term to see what it means.

By the end of this lesson you will be able to

  • Explain what a CDN does and why CloudFront makes a site faster and cheaper to run: lower latency, origin offload, fewer long-distance handshakes.
  • Describe CloudFront’s layers (edge locations, Regional Edge Caches, Origin Shield) and follow a request through a cache miss, a hit, a revalidation and an origin outage.
  • Choose the right origin (S3 bucket, S3 website endpoint, custom HTTP origin, VPC origin) and keep an S3 origin private with Origin Access Control and a bucket policy.
  • Route paths to origins with cache behaviours, and design a cache key and TTLs with cache policies and origin request policies.
  • Set up origin failover with an origin group, HTTPS with an ACM certificate in us-east-1, and logging.
  • Pick between CloudFront, S3 Cross-Region Replication and S3 Transfer Acceleration from the wording of an exam question.

#Why put a cache near your users

#The distance problem

Light in fibre covers roughly 200 km per millisecond, and real cables never run in a straight line. A packet from Dhaka to a server in North Virginia (us-east-1) and back takes about 230 ms. That is one round trip, and a web page needs many:

  • A new HTTPS connection costs one round trip for the TCP handshake and one for TLS 1.3 (two for older TLS) before the first request is even sent, then one more for the request and the answer: about 3 round trips ≈ 700 ms before the first byte arrives.
  • A product page loads dozens of photos, scripts and style sheets. Browsers reuse connections, but every request still waits at least one round trip.
  • The further away the server, the more packets get lost on the way, and every loss stalls TCP.

The cure is not a faster server; it is a shorter distance. If a copy of the photo sits in a data centre 20–30 ms away, the same three round trips take under 100 ms.

#What CloudFront is

Amazon CloudFront is AWS’s content delivery network (CDN): a worldwide network of caching servers that sits between your users (the viewers) and your servers (the origins). It is a global service: you do not pick a Region for it, and its configuration is pushed to every location.

What you get by putting it in front of a site or an API:

  • Lower latency. Viewers connect to a nearby location; TLS is finished there, close to them.
  • Origin offload. Popular files are served from caches, so the origin handles a small fraction of the requests. During an Eid sale or an election night, that is the difference between a fast site and a dead one.
  • A faster path for what is not cached. Requests that must reach the origin (an API call, a checkout) travel the long distance over the AWS backbone, on connections CloudFront keeps open, instead of over the public internet.
  • Protection. Being spread worldwide, CloudFront absorbs network floods; AWS Shield Standard is included at no cost, and AWS WAF can filter requests at the edge. That is lesson 11.2.
  • Cheaper delivery. Data transfer from AWS origins (S3, ALB, EC2) to CloudFront is free, and CloudFront’s own transfer prices are lower than S3’s for traffic to the internet.

CloudFront is not only for static files. It also speeds up dynamic content (HTML built per request, API responses) because of the warm connections and the backbone, and it carries WebSocket and gRPC traffic. What it does not do is run your application: compute at the edge is limited to small functions (lesson 11.3).

#How CloudFront is built

#Edge locations and Regional Edge Caches

CloudFront has two tiers of caches in front of your origin, plus an optional third:

  1. Edge locations, also called points of presence (PoPs): more than 750 of them in over 100 cities and 50 countries, plus more than 1,140 smaller embedded PoPs inside internet providers’ networks. DNS sends each viewer to the PoP that can serve them best, normally the one with the lowest latency. For a viewer in Dhaka that is typically a PoP in a nearby country, such as Kolkata or Singapore. PoPs are small and keep the most popular objects.
  2. Regional Edge Caches: 15 larger caches in AWS Regions, each shared by many PoPs. When a PoP misses, it asks its Regional Edge Cache before going to the origin. They keep objects longer, which helps the long tail: product photos nobody opened today, last week’s news, a video that suddenly becomes popular again.
  3. Origin Shield (optional, extra charge): one more cache layer in the Region you choose, closest to your origin, in front of all the Regional Edge Caches. See “Origin Shield: one cache in front of the origin” below.

Three exceptions to the path through the Regional Edge Cache are worth knowing: PUT, POST, PATCH, OPTIONS and DELETE go straight from the PoP to the origin; requests that CloudFront decides at request time are dynamic (not cacheable) also go direct; and when an S3 origin is in the same Region as the Regional Edge Cache, the PoP skips that tier and talks to S3 itself.

Watch one photo go through these tiers, including what happens when its TTL runs out and when the origin is down:

One photo, many viewers: the life of a cached object

Bazaar Bari keeps its product photos in a bucket in North Virginia. Shoppers in Bangladesh reach a nearby CloudFront edge location instead. Watch when the request travels all the way to the origin, and when it does not.

Scenario

Nobody near Dhaka has asked for this photo yet, so no cache has it.

us-east-1
Viewer 1Dhaka
Viewer 2Chattogram
Edge locationnearby PoP
Regional Edge Cachebigger, slower tier
Origin bucketproduct photos
GET /img/saree-42.jpg

Cache state for /img/saree-42.jpg

Edge copyRegional copyAge / TTLx-cache
nonenone——
Step 1 of 5
1

Viewer 1 opens a product page. DNS for shop.example.com has already sent the browser to the CloudFront PoP with the lowest latency, not to Virginia. The browser asks that PoP for the photo.

#The distribution

A distribution is one CloudFront configuration. When you create one, CloudFront gives it a domain name such as d111111abcdef8.cloudfront.net. A distribution holds:

  • one or more origins (up to 100) and optional origin groups for failover;
  • cache behaviours: which paths go to which origin, and how they are cached;
  • general settings: alternate domain names (your own names, such as shop.example.com, up to 100), the TLS certificate, the default root object, logging, a price class (which parts of the network to use, lesson 11.2), an AWS WAF web ACL, IPv6 and HTTP/2 and HTTP/3 support.

To serve the site at your own name, add the name as an alternate domain name, attach a certificate that covers it, and point DNS at the distribution: in Route 53 an Alias record to the distribution, which also works at the zone apex (example.com) and costs nothing per query (lesson 8.2). Elsewhere, a CNAME to d111111abcdef8.cloudfront.net for a subdomain.

Changes to a distribution are deployed to every location; that takes a few minutes, during which the status is “Deploying”.

#Origins

An origin is where CloudFront fetches what it does not have. The kinds you will meet:

OriginWhat it isHow it is protectedTypical use
S3 bucket (REST endpoint, bucket.s3.region.amazonaws.com)An S3 origin; CloudFront can sign its requestsOrigin Access Control + bucket policy; bucket stays privateStatic sites, images, video files, downloads; also uploads to S3 through CloudFront
S3 website endpoint (bucket.s3-website-region.amazonaws.com)A custom origin that speaks HTTP onlyNone from CloudFront: the bucket must be publicSites that need S3’s index documents in every folder and its redirect rules (lesson 10.3)
Custom HTTP originAny server reachable over HTTP or HTTPS on the internet: a public ALB, EC2 with a public address, API Gateway, a Lambda function URL, a server in your own data centreSecurity group with the CloudFront prefix list, a secret header (lesson 11.2)Dynamic sites, APIs, anything not in S3
VPC originA private ALB, NLB or EC2 instance in a private subnetNo public address at allApplications that must not be reachable from the internet (lesson 11.2)
AWS media servicesAWS Elemental media servicesService-specificLive and on-demand video streaming

For every origin you also set: an optional origin path (fetch from /production inside the bucket), custom headers to add to every origin request, and for custom origins the origin protocol policy (HTTP only, HTTPS only, or match the viewer) and ports. Three timers decide how CloudFront treats a slow or dead origin: connection timeout (default 10 s, 1–10), connection attempts (default 3, 1–3) and response timeout (default 30 s, 1–120). The defaults mean a dead origin can make a viewer wait about 30 seconds before anything happens.

#Cache behaviours: which path goes where

A cache behaviour is a rule that matches a path pattern and says how to handle matching requests. A distribution has a list of them (up to 75), checked in order of precedence; the first match wins. The last one is always the default behaviour, *, which catches everything else and cannot be deleted.

Each behaviour sets:

  • the origin (or origin group) to use;
  • the viewer protocol policy: allow HTTP and HTTPS, redirect HTTP to HTTPS, or HTTPS only;
  • the allowed methods: GET and HEAD; GET, HEAD and OPTIONS; or all seven (adding PUT, POST, PATCH and DELETE); and whether OPTIONS responses are cached;
  • the cache policy (cache key and TTLs) and origin request policy (what to forward), explained below, and an optional response headers policy (security headers, CORS headers);
  • edge functions, signed URLs or cookies, field-level encryption and compression.

Path patterns are case-sensitive and support * (any characters) and ? (one character): /images/*, /api/*, *.mp4.

Cache behaviours: one domain, several origins

shop.example.com has three cache behaviours, checked in order: /images/* goes to a bucket and is cached for a day, /api/* goes to the ALB and is never cached, and the default (*) behaviour catches everything else.

Scenario

us-east-1
Browserin Dhaka
CloudFrontshop.example.com
Bucketsimages, site files
Cart APIALB
GET /images/saree-42.jpg

Matched cache behaviour

Path patternOriginCache policyAllowed methods
/images/*images bucketCachingOptimizedGET, HEAD
Step 1 of 3
1

The browser asks for /images/saree-42.jpg. CloudFront compares the path with the behaviours in precedence order; /images/* is first and matches.

#Keeping an S3 origin private: Origin Access Control

If the bucket behind CloudFront were public, anybody could skip CloudFront and download straight from S3: no WAF, no geo restriction, no signed URLs, no edge logs, and a full S3 bill for every byte. Origin Access Control (OAC) closes that door:

  • CloudFront signs every request to the bucket with AWS Signature Version 4, as the CloudFront service, and identifies the distribution making it. With the recommended setting (“Sign requests”) the connection to S3 is always HTTPS.
  • The bucket keeps Block Public Access on. Its bucket policy allows the service principal cloudfront.amazonaws.com, but only for requests made on behalf of your distribution, using the AWS:SourceArn condition.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCloudFrontServicePrincipalReadOnly",
      "Effect": "Allow",
      "Principal": { "Service": "cloudfront.amazonaws.com" },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::bazaarbari-images-example/*",
      "Condition": {
        "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EDFDVBD6EXAMPLE"
        }
      }
    }
  ]
}

Three details that come up in real setups and in exam questions:

  • The condition is the security. Without it, any CloudFront distribution in any account, including one an attacker creates, could read the bucket.
  • SSE-KMS. If objects are encrypted with a customer managed KMS key, the key policy must also allow cloudfront.amazonaws.com to use kms:Decrypt (same AWS:SourceArn condition), otherwise viewers get 403 (lesson 10.8).
  • Uploads. To accept PUT through CloudFront, the behaviour must allow all methods and the bucket policy must also allow s3:PutObject for the distribution. OAC supports these dynamic requests.

OAC also requires the bucket’s Object Ownership to be “bucket owner enforced” (the default for new buckets), and it cannot be used with a website endpoint origin: there is nothing to sign for an anonymous HTTP endpoint.

#The legacy way: origin access identity

Before 2022 the same job was done by an origin access identity (OAI): a special CloudFront user that the bucket policy names as its principal (arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity …). It still works for reading SSE-S3 buckets in older Regions, but it does not support SSE-KMS, does not support every kind of upload, and does not work in S3 Regions launched after December 2022. AWS now calls OAI legacy and recommends OAC. Older exam questions and the slides of a few years ago say OAI; read either as “CloudFront can read a private bucket, nobody else can”.

To migrate without an outage: add a statement for the distribution (OAC) next to the OAI statement in the bucket policy, switch the origin to OAC, wait for the deployment, then remove the OAI statement.

Origin Access Control: only CloudFront may read the bucket

The photo bucket is private. CloudFront signs every request it sends to S3, and the bucket policy trusts those signatures only when they come from Bazaar Bari’s own distribution.

Scenario

us-east-1
Shopper
Scraperskips CloudFront
CloudFrontsigns with OAC
Private bucketno public access
KMS key
GET /img/saree-42.jpg

Bucket bazaarbari-images-example

Block Public AccessBucket policy allowsEncryption
Onthis distribution onlySSE-S3
Step 1 of 4
1

A shopper asks shop.example.com for a photo. On a miss, the edge must fetch it from the bucket, which has Block Public Access on.

Self-checkQuestion

An S3 bucket serves product photos through CloudFront. The security team requires that the photos can only be downloaded through CloudFront, never directly from S3. What should the architect configure?

#The cache key: what makes two requests the same

#What is in the key

The cache key is the set of values CloudFront uses to decide whether a request matches something already in the cache. By default it is the distribution’s domain name plus the URL path. You can add, through a cache policy:

  • query strings: none, all, an allow list or all except a deny list;
  • headers: none or a list (for example CloudFront-Viewer-Country, or a normalised Accept-Encoding, which CloudFront adds itself when compression is on, so gzip and Brotli copies are cached separately);
  • cookies: none, all, an allow list or all except a deny list.

The rule that decides everything: put into the cache key exactly the values that change the response, and nothing else.

  • Leave out something that changes the response (the size query string of an image resizer), and viewers get the wrong copy: a thumbnail on the zoom page.
  • Put in something that does not change the response (a fbclid tracking parameter, the full User-Agent, a session cookie on a photo), and every variation is a separate cached copy. The hit ratio collapses, the origin takes the load, and you pay for it.

#Cache policy and origin request policy

Two separate policies are attached to each behaviour, and the difference is a classic question:

Cache policyOrigin request policy

  • Decides the cache key: which query strings, headers and cookies make a request different.
  • Holds the TTLs (minimum, default, maximum) and the compression settings.
  • Everything in the cache key is also forwarded to the origin automatically.
  • Managed examples: CachingOptimized (no query strings, headers or cookies; TTL 1 s / 1 day / 365 days), CachingDisabled (all TTLs 0), UseOriginCacheControlHeaders.
  • Decides what else is forwarded to the origin on a miss, without adding it to the cache key.
  • Use it when the origin needs a value that does not change the cached answer (a header for its logs, a user’s country for analytics), or when caching is disabled and the origin needs everything.
  • Managed examples: AllViewer, AllViewerExceptHostHeader (for API Gateway and Lambda function URLs, which need their own Host), CORS-S3Origin.
  • Nothing here can make the cache key bigger.

A dynamic API behind CloudFront is usually CachingDisabled + AllViewer (or AllViewerExceptHostHeader): nothing is cached, and the origin sees every header, cookie and query string. Static files from S3 are usually CachingOptimized with no origin request policy, or CORS-S3Origin when browsers fetch them cross-origin. Older distributions use “legacy cache settings” on the behaviour instead of policies; the policies replaced them.

#TTL: how long a copy lives

#Minimum, default and maximum TTL

The TTL (time to live) is how long CloudFront keeps a copy before it has to check with the origin again. The cache policy holds three numbers, and the origin’s own headers decide where in that range the TTL falls:

What the origin sendsTTL CloudFront uses
Cache-Control: max-age=NN, but never less than the minimum TTL or more than the maximum TTL
Cache-Control: s-maxage=N (with or without max-age)N, within the same bounds. s-maxage is for shared caches like CloudFront; browsers use max-age
Expires: <date> (and no max-age)Until that date, within the bounds. max-age wins if both are present
NothingThe default TTL (24 hours if you set nothing else), or the minimum TTL if that is larger
no-cache, no-store or privateRespected if the minimum TTL is 0; cached for the minimum TTL if it is above 0

The last row is a trap: the managed CachingOptimized policy has a minimum TTL of 1 second, so an origin’s no-store is overridden and the response is cached for one second. For responses that must never be cached, use a policy with minimum TTL 0, such as CachingDisabled or UseOriginCacheControlHeaders.

Two more facts: a viewer’s own Cache-Control: no-cache in a request is ignored (users cannot force CloudFront to the origin), and a TTL is a maximum, not a promise: an object nobody asks for may be evicted earlier to make room.

#Hit, miss, revalidation, and serving stale

Every response from CloudFront carries headers that show what happened:

  • x-cache: Hit from cloudfront: served from the edge cache.
  • x-cache: Miss from cloudfront: fetched from the Regional Edge Cache or the origin (also shown for requests that are never cached).
  • x-cache: RefreshHit from cloudfront: the copy had expired; CloudFront asked the origin with a conditional request (If-None-Match with the ETag, or If-Modified-Since), the origin said 304 Not Modified, and the cached copy was served and renewed. Cheap: no body crosses the ocean.
  • x-cache: Error from cloudfront: an error, from the origin or CloudFront itself.
  • age: seconds since the copy was fetched. x-amz-cf-pop: which PoP answered (a code like SIN2-P1). x-amz-cf-id: the request ID for support and logs.

When the origin is unreachable and the copy has expired, CloudFront can serve the stale copy instead of an error if the origin sent Cache-Control: stale-if-error=N (or the minimum TTL is above 0). stale-while-revalidate=N goes further: after expiry CloudFront serves the old copy immediately while it fetches a fresh one in the background. Errors from the origin (4xx and 5xx) are cached too, for 10 seconds by default, so a failing origin is not flooded; you can change this per status code with custom error responses (lesson 11.2).

#What CloudFront does not cache

  • Responses to PUT, POST, PATCH and DELETE are never cached; CloudFront just proxies them. GET and HEAD responses are cached; OPTIONS responses only if you choose.
  • Anything a TTL of 0 applies to: CachingDisabled, or the origin’s no-store with a minimum TTL of 0.
  • Files larger than 50 GB in a single GET response.

Now try it. Change the cache key and the TTL, and see what happens to the hit ratio and to the origin:

Cache key and TTL lab

Bazaar Bari’s Eid sale: 120,000 photo requests an hour for 400 product photos, from 15,000 shoppers, through 12 PoPs and 3 Regional Edge Caches. Photo URLs look like /img/saree-42.jpg?size=thumb&fbclid=… . Choose what goes into the cache key and how long copies live, then run an hour of traffic.

Query strings in the cache key

Header in the cache key

Cookies in the cache key

TTL

Press “Run one hour of traffic” to see the result.

#When the origin fails: origin groups

#Origin failover

An origin group has two origins: a primary and a secondary. A behaviour that points at the group sends every cache miss to the primary. If the primary returns one of the status codes you chose (any of 400, 403, 404, 416, 429, 500, 502, 503, 504), or cannot be connected to (counted as 503), or times out (counted as 504), CloudFront sends the same request to the secondary and returns its answer.

What to know about it:

  • It works per request, with no health check and no memory: the next miss goes to the primary again. Lower the connection timeout and attempts on the primary, or each miss waits up to 30 seconds before failing over.
  • It applies only to GET, HEAD and OPTIONS. Uploads and other writes are not failed over.
  • A typical pair is a bucket and its Cross-Region Replication copy in another Region (lesson 10.4), or two load balancers in two Regions. Up to 10 origin groups per distribution.

Origin failover: a second origin for the same files

The photo bucket is copied to Mumbai with Cross-Region Replication. An origin group lists Virginia as primary and Mumbai as secondary, and the /images/* behaviour points at the group instead of at one bucket.

Scenario

us-east-1
ap-south-1
ShopperDhaka
CloudFrontorigin group
Primarymain bucket
SecondaryCRR replica
GET /images/saree-42.jpgGET (miss)

Origin group “photos”

PrimarySecondaryFailover onConnect timeout × tries
bucket, us-east-1replica, ap-south-1500, 502, 503, 50410 s × 3 (default)
Step 1 of 2
1

On a cache miss, CloudFront always tries the primary origin first.

For a whole application that must move to another Region, origin groups are one piece: DNS failover with Route 53 health checks (lessons 8.3 and 8.4) or Global Accelerator (lesson 11.4) move all traffic, including writes.

#Origin Shield: one cache in front of the origin

Each Regional Edge Cache that misses goes to the origin on its own. With 15 of them, a popular new object can reach the origin many times, and some origins hate that: a live-video packager, an on-the-fly image resizer, a server in your own data centre with a thin link. Origin Shield adds one more cache in the Region you choose, the one closest to your origin. All Regional Edge Caches then go through it, and it collapses simultaneous requests for the same object into one origin request.

  • Benefits: a higher overall hit ratio, much less origin load, and the traffic stays on the CloudFront network all the way to your origin.
  • Cost: a charge per request that passes through Origin Shield as an extra layer (requests from the Regional Edge Cache in the same Region are not charged).
  • It is a setting of the origin, works with origins inside or outside AWS, with origin groups, and in a multi-CDN setup where other CDNs pull from CloudFront.
  • It is not worth it for content that is not cacheable or is rarely requested.

#HTTPS with CloudFront

There are two connections to secure: viewer → CloudFront and CloudFront → origin.

  • Viewer protocol policy (per behaviour): HTTP and HTTPS, Redirect HTTP to HTTPS (CloudFront answers 301 with the https address, the usual choice for websites) or HTTPS only (HTTP requests get 403, common for APIs).
  • Origin protocol policy (custom origins): HTTP only, HTTPS only or Match viewer. With HTTPS the origin’s certificate must be valid and must match the origin domain name, otherwise CloudFront returns 502 Bad Gateway. S3 REST origins with OAC are always HTTPS; website endpoints are always HTTP.
  • Your own domain needs a certificate on the distribution. The default *.cloudfront.net name has one already. For shop.example.com, request a free public certificate in AWS Certificate Manager (ACM) in us-east-1 (N. Virginia), whatever Region your origin is in. A certificate in another Region does not appear in the CloudFront console. (For an ALB origin, the ALB’s own certificate stays in the ALB’s Region, lesson 6.4.) The certificate must cover every alternate domain name.
  • SNI or dedicated IP. CloudFront uses SNI (Server Name Indication) by default: the browser says which host name it wants during the TLS handshake, so one set of edge addresses can serve many certificates. It is free and every current browser supports it. For very old clients without SNI there is a dedicated IP option that costs about $600 a month per certificate. You also choose a security policy that sets the minimum TLS version viewers may use.

The certificate lives in us-east-1 for the same reason Lambda@Edge functions are created there (lesson 11.3): CloudFront is global, and its control plane uses that Region.

#Logs and monitoring

CloudFront can record every request. Standard logs (access logs) are delivered in batches, usually within minutes, to S3, CloudWatch Logs or Amazon Data Firehose; the logging itself is free, you pay for where they are stored. Each line has the time, PoP, client IP, URL, status, bytes, time taken and the result type (Hit, Miss, RefreshHit, Error, OriginShieldHit…). Real-time logs go to a Kinesis data stream within seconds, with the fields and sampling rate you choose, at a charge per million log lines; use them for live dashboards and alarms. CloudFront also publishes CloudWatch metrics (requests, bytes, 4xx and 5xx error rates, and, as a paid option, cache hit rate and origin latency), and AWS CloudTrail records configuration changes.

#What it costs

Pay-as-you-go CloudFront charges for data transfer out to viewers (per GB, cheaper per GB as volume grows, different by continent), HTTP and HTTPS requests (per 10,000), and extras: invalidations beyond the free 1,000 paths a month, Origin Shield, real-time logs, edge functions, dedicated IP certificates. The always-free tier covers 1 TB of transfer out and 10 million requests every month. Transfer from AWS origins to CloudFront is free, so a busy site served from S3 through CloudFront is usually cheaper than the same site served straight from S3. Price classes, which leave out the most expensive parts of the world to save money, are in lesson 11.2.

#CloudFront vs S3 Cross-Region Replication

Both are ways of getting data closer to users far from the bucket, and the exam likes to put them side by side. They work in completely different ways.

CloudFrontS3 Cross-Region Replication (CRR)
What it doesCaches copies of what viewers request, at hundreds of edge locationsCopies every new object into a bucket in another Region you choose
Where the copies areThe whole global edge network, automaticallyOnly in the Regions you set up, one rule (destination) each
When a copy is madeOn the first request at each location, then kept for the TTL (often a day)Asynchronously after each write, usually within seconds to minutes (99.99% within 15 minutes with Replication Time Control)
FreshnessCan be stale until the TTL ends or you invalidateNear real time
RequirementsA distribution in front of the originVersioning on both buckets, an IAM role, a replication rule; existing objects need Batch Replication
WritesPassed through to the one originThe application writes to its local bucket; writes to the replica are not copied back unless you set up two-way replication
Best forStatic content that must be fast everywhere: images, video, CSS, JavaScript, downloads, also dynamic pages and APIsDisaster recovery, compliance (a copy in another country or Region), low-latency access for applications in a few chosen Regions

CloudFront or Cross-Region Replication?

Both put data closer to far-away users, in very different ways. CloudFront keeps temporary copies of what people read, at the edge. CRR keeps a full, permanent copy of every new object in another Region’s bucket.

Scenario

us-east-1
ap-south-1
Shoppersworldwide
Mumbai appreads and writes
CloudFrontedge caches
Source bucket
Replica bucket
GET photomiss → fetch

How the copy behaves

Copy lives inCopied whenFreshnessWrites
hundreds of edge cacheson first requestuntil TTL endspassed to origin
Step 1 of 3
1

Shoppers everywhere open product photos. Each nearby edge fetches a photo the first time someone asks for it.

The notes add one more pairing, and it needs a correction: for “staff far away need low-latency uploads to a bucket”, CRR helps only if each office writes to its own Region’s bucket. When everybody must upload into one bucket, the standard answer is S3 Transfer Acceleration (lesson 10.6), which enters the AWS network at a nearby edge location. Uploading through a CloudFront distribution with PUT uses the same idea and works, but it is not what exam questions about uploads expect.

#What goes wrong

  • 403 from an S3 origin. Missing or wrong bucket policy (no AWS:SourceArn, wrong distribution ID), the key does not exist (S3 says 403, not 404, when CloudFront cannot list the bucket), no default root object for /, or SSE-KMS without a key policy statement.
  • Users see an old file after an update. The copy is still within its TTL. Invalidate the path or, better, version the file name (lesson 11.2). Check age in the response.
  • Low hit ratio. Too much in the cache key: all query strings, all cookies, User-Agent. Look at the URLs in the standard logs.
  • One user sees another user’s data. A personal response cached with a key that does not include the session: use CachingDisabled for such paths, or include the right value in the key.
  • 502 Bad Gateway. CloudFront could not complete TLS with a custom origin (certificate expired, self-signed, or not matching the origin domain name), or the origin closed the connection.
  • 504 Gateway Timeout. The origin did not answer in time: a security group or network ACL blocking CloudFront, an overloaded server, or a response slower than the response timeout.
  • The certificate does not appear in the console. It was requested in a Region other than us-east-1.
  • The site works at d111111abcdef8.cloudfront.net but not at shop.example.com. The alternate domain name is missing from the distribution, the certificate does not cover it, or DNS does not point at the distribution yet.
  • “My change is not live.” The distribution is still deploying, or the old response is still cached.

#CloudFront in system design

  • The standard static front end. A private S3 bucket with OAC, a distribution with an ACM certificate and a Route 53 Alias, CachingOptimized, long TTLs and versioned file names. Cheap, fast and safe; most serverless web apps start here.
  • One domain for site and API. Path behaviours route /api/* to an ALB or API Gateway with caching off, and everything else to S3. No CORS, one certificate, one WAF.
  • Absorbing spikes. Short TTLs (even 1–5 seconds) on hot dynamic pages turn a flood of identical requests into a trickle at the origin. Add Origin Shield for fragile origins.
  • Read availability across Regions. CRR keeps a second bucket current; an origin group fails reads over to it.
  • Global upload and download in one place. Uploads with PUT through CloudFront or Transfer Acceleration, downloads cached at the edge, and private content with signed URLs (lesson 11.2).
  • Know its limits. CloudFront is HTTP-based (HTTP, WebSocket, gRPC). For TCP or UDP applications, static IP addresses as the main requirement, or fast Regional failover of non-HTTP traffic, look at Global Accelerator (lesson 11.4).

#Try it yourself

Create a private bucket, a distribution with OAC, and watch a miss become a hit. Replace the IDs with yours.

# 1. A private bucket with a photo (Block Public Access stays on, the default)
aws s3 mb s3://bazaarbari-images-example --region us-east-1
aws s3 cp saree-42.jpg s3://bazaarbari-images-example/img/saree-42.jpg \
  --cache-control "max-age=86400"

# 2. An origin access control that always signs
aws cloudfront create-origin-access-control --origin-access-control-config \
  Name=bazaarbari-oac,SigningProtocol=sigv4,SigningBehavior=always,OriginAccessControlOriginType=s3

# 3. The managed cache policies and their IDs
aws cloudfront list-cache-policies --type managed \
  --query "CachePolicyList.Items[].CachePolicy.[Id,CachePolicyConfig.Name]" --output table

# 4. Create the distribution from a config file (origin + OAC ID + default behaviour with
#    CachingOptimized, ViewerProtocolPolicy redirect-to-https, DefaultRootObject index.html)
aws cloudfront create-distribution --distribution-config file://dist-config.json
aws cloudfront get-distribution --id EDFDVBD6EXAMPLE --query "Distribution.Status"   # Deployed?

# 5. Allow only this distribution in the bucket policy (the JSON from the lesson)
aws s3api put-bucket-policy --bucket bazaarbari-images-example --policy file://oac-policy.json

Now look at the headers. Run the same request twice:

curl -sI https://d111111abcdef8.cloudfront.net/img/saree-42.jpg | grep -iE "x-cache|age|x-amz-cf-pop|cache-control"
# x-cache: Miss from cloudfront          ← first request
# x-amz-cf-pop: SIN2-P1                  ← the PoP that answered (yours will differ)

curl -sI https://d111111abcdef8.cloudfront.net/img/saree-42.jpg | grep -iE "x-cache|age"
# x-cache: Hit from cloudfront
# age: 12                                ← seconds since the copy was fetched

# Direct access to the bucket must fail
curl -sI https://bazaarbari-images-example.s3.us-east-1.amazonaws.com/img/saree-42.jpg | head -1
# HTTP/1.1 403 Forbidden

# A different query string is the same object only if the cache policy ignores query strings
curl -sI "https://d111111abcdef8.cloudfront.net/img/saree-42.jpg?fbclid=abc" | grep -i x-cache

Useful extras: aws cloudfront get-distribution-config --id EDFDVBD6EXAMPLE to see every setting (and the ETag you need for update-distribution), aws cloudfront list-distributions --query "DistributionList.Items[].[Id,DomainName,Aliases.Items]", and aws acm request-certificate --domain-name shop.example.com --validation-method DNS --region us-east-1 for the certificate. Delete the distribution when you are done: disable it, wait until it is deployed, then delete-distribution with its ETag.

#Summary

Key takeaways

  • CloudFront is AWS’s CDN: a global service that caches content at 750+ edge locations (PoPs) backed by 15 Regional Edge Caches, cutting latency and origin load. It also speeds up dynamic content over the AWS backbone and gives DDoS protection at the edge.
  • A request goes viewer → nearest PoP → Regional Edge Cache → (optional Origin Shield) → origin. PUT, POST, PATCH, DELETE and OPTIONS go straight from the PoP to the origin and are never cached.
  • A distribution (d111111abcdef8.cloudfront.net) has origins, origin groups, cache behaviours (path patterns, first match wins, default * last, case-sensitive) and general settings (alternate domain names, certificate, price class, WAF, logs).
  • Origins: S3 bucket (REST endpoint, secured with OAC), S3 website endpoint (a custom HTTP origin, public, no OAC), any custom HTTP origin (public ALB, EC2, on-premises), VPC origins for private ALB/NLB/EC2.
  • OAC: CloudFront signs requests; bucket private; bucket policy allows cloudfront.amazonaws.com with AWS:SourceArn = your distribution; KMS key policy for SSE-KMS. OAI is the legacy version (no SSE-KMS, no new Regions).
  • Cache key = domain + path, plus whatever query strings, headers and cookies the cache policy adds. Include exactly what changes the response. The origin request policy forwards extra values without changing the key.
  • TTL: origin’s max-age / s-maxage / Expires, clamped between the minimum and maximum TTL; default 24 h when the origin says nothing. Expired copies are revalidated (304 → RefreshHit); stale-if-error serves old copies when the origin is down; errors are cached 10 s by default.
  • Origin groups: primary and secondary, failover per request on chosen status codes, timeouts or connection failures, GET/HEAD/OPTIONS only. Default 3 × 10 s connection attempts.
  • HTTPS: viewer protocol policy (redirect or HTTPS only), origin protocol policy, ACM certificate in us-east-1, SNI (free) vs dedicated IP.
  • CloudFront vs CRR: CloudFront = cached copies everywhere for a TTL, for global reads; CRR = full near-real-time copy in chosen Regions, for DR, compliance and Regional low-latency access; faster uploads to one bucket = Transfer Acceleration.