Ravindra BagaleCourses & study guides मराठी Track your progress

CloudFront Cache Behaviors, TTL and Invalidation Step by Step

In CloudFront Origins Explained we sent /static/* to S3 and everything else to an ALB. The rule that did that is a cache behavior. This chapter goes deep: path patterns and their order, TTLs, Cache-Control headers, cache policies vs origin request policies, the cache key, and how to update files with invalidations or versioned names.

What you'll learn in this chapter

  • Cache behaviors, path patterns and their order
  • Minimum, default and maximum TTL with Cache-Control
  • Cache policy vs origin request policy
  • The cache key: query strings, cookies, headers
  • Invalidation vs versioned file names

1. A story: the old price list

A shop prints its price list and gives copies to 20 branch counters. Next week prices change. The head office has the new list, but branches keep handing out the old copies until someone tells them to throw them away.

CloudFront edges are those branches. The TTL is how long each branch keeps a copy. Invalidation is the phone call that says "throw it away".

2. Cache behaviors and path patterns

Why do we need this?

Images can be cached for a year; the login API must never be cached. One distribution needs different rules for different paths.

What is it?

A cache behavior = a path pattern + an origin + settings (viewer protocol, allowed methods, cache policy, origin request policy, functions, signed URL requirement). CloudFront checks behaviors top to bottom and uses the first match. The Default (*) behavior is always last and catches everything else.

OrderPath patternOriginCache
0/api/*ALBCachingDisabled
1/static/*S31 year (versioned files)
2*.jpgS31 day
3/images/private/*S3Signed URL required
Default*ALBShort, e.g. 60 s for HTML

Trap: /images/private/photo.jpg matches *.jpg (order 2) before /images/private/* (order 3), so the private rule never runs. Put specific patterns above general ones. Patterns are case sensitive; * matches any characters and ? exactly one.

3. TTL and Cache-Control

Why do we need this?

Too short and the origin works hard. Too long and users see old files.

What is it?

Your origin can send Cache-Control: max-age=600 (or s-maxage for shared caches only). The cache policy has three TTLs that frame it:

TTLMeaningCachingOptimized value
MinimumCache at least this long, even if the origin says less1 s
DefaultUsed when the origin sends no Cache-Control or Expires86,400 s (1 day)
MaximumNever cache longer than this, even if the origin says more31,536,000 s (1 year)
Origin sendsMin 0, Default 86400, Max 3600Edge keeps it
max-age=600-600 s
nothing-3600 s (default capped by max)
max-age=86400-3600 s (capped by max)
no-cache / no-store / privateMin 0Not cached
StackSend Cache-Control
S3 uploadaws s3 cp app.3f9a.js s3://b/static/ --cache-control "public,max-age=31536000,immutable"
Node/Expressexpress.static("public",{maxAge:"1y",immutable:true})
Flaskresp.headers["Cache-Control"]="public, max-age=600"
PHPheader("Cache-Control: public, max-age=600");
SpringResponseEntity.ok().cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES))
.NET[ResponseCache(Duration = 600)]
nginxlocation /static/ { add_header Cache-Control "public, max-age=31536000, immutable"; }
ApacheHeader set Cache-Control "max-age=600, public"

4. Cache policy vs origin request policy

Why do we need this?

Your app may need a cookie to work, but if every cookie value becomes part of the cache key, every user gets a separate copy and the hit rate drops to zero.

What is it?

PointCache policyOrigin request policy
ControlsTTLs + the cache key (what makes two requests "the same")Extra values sent to the origin on a miss
Affects hit rateYesNo
Managed examplesCachingOptimized, CachingDisabled, UseOriginCacheControlHeadersAllViewer, CORS-S3Origin, AllViewerExceptHostHeader
RuleValues in the cache key are always sent to the origin tooAdd what the origin needs but caching should ignore

5. The cache key

Why do we need this?

The cache key decides whether two requests share one cached copy. A bigger key means more copies and more misses.

What is it?

By default the key is the domain plus the URL path. You can add query strings, cookies and headers. Add only what really changes the response.

RequestPut in cache key?Why
/products?page=2Query string page: yesDifferent content per page
/products?utm_source=fbutm_*: noSame content; would split the cache
Cookie: lang=mrOnly cookie langPage differs by language
Cookie: _ga=...NoAnalytics only
Accept-EncodingHandled by enabling Gzip/Brotli in the policyCompressed and plain copies kept apart

6. Invalidation vs versioned file names

Why do we need this?

You changed a file. Edges still hold the old copy until TTL ends. You need a way to update now.

What is it?

PointInvalidationVersioned names (app.3f9a.js)
HowTell CloudFront to drop paths from every edgeNew content = new file name; HTML points to it
CostFirst 1,000 paths per month free, then $0.005 per path; /* counts as one pathFree
SpeedUsually done within a few minutesInstant: new URL is a guaranteed miss
RollbackInvalidate againPoint HTML back to the old name
Best forindex.html, emergency fixesJS, CSS, images (Vite, webpack, Angular do it for you)
# invalidate one file, then wait for it
aws cloudfront create-invalidation --distribution-id E1ABCDEF2GHIJ --paths "/index.html"
aws cloudfront wait invalidation-completed --distribution-id E1ABCDEF2GHIJ --id I2J3K4L5M6N7O8

Ravindra Bagale's Tip

Common pattern: index.html with a short TTL (60 s) or invalidated on each deploy; every asset versioned and cached for a year.

7. Lab: a stale file, then fix it

How to do it (step by step)

  1. Use a distribution with a private S3 origin and OAC (the lab from What Is Amazon CloudFront), default behavior with CachingOptimized.
  2. echo "price v1" > price.txt; aws s3 cp price.txt s3://yourname-cf-lab/price.txt.
  3. curl -s https://dXXXX.cloudfront.net/price.txt twice. Expected: price v1; second time X-Cache Hit (check with -I).
  4. Change it: echo "price v2" > price.txt; aws s3 cp price.txt s3://yourname-cf-lab/price.txt.
  5. curl -s https://dXXXX.cloudfront.net/price.txt. Expected: still price v1. Why: the edge copy lives for the 1-day default TTL.
  6. Invalidate: aws cloudfront create-invalidation --distribution-id EXXXX --paths "/price.txt". Note the Id in the output.
  7. aws cloudfront wait invalidation-completed --distribution-id EXXXX --id IXXXX. Expected: returns with no output when done.
  8. curl -sI https://dXXXX.cloudfront.net/price.txt | grep -i x-cache; curl -s https://dXXXX.cloudfront.net/price.txt. Expected: Miss, price v2.
  9. Now the versioned way: upload price.v3.txt with --cache-control "public,max-age=31536000,immutable" and fetch it. Expected: new content at once, no invalidation.
  10. Cache key test: curl -sI "https://dXXXX.cloudfront.net/price.txt?x=1" | grep -i x-cache. Expected: Hit. Why: CachingOptimized ignores query strings, so ?x=1 is the same key.

Cleanup

  1. Delete the test objects; disable and delete the distribution if you made one only for this lab.

8. Interview questions

Q. In what order are cache behaviors evaluated?

Top to bottom by precedence; the first matching path pattern wins; Default (*) is last.

Q. Origin sends max-age=86400 but max TTL is 3600. How long is it cached?

3600 seconds. The max TTL caps it.

Q. Cache policy vs origin request policy?

Cache policy sets TTLs and the cache key; origin request policy adds values sent to the origin without affecting the cache key.

Q. Why is your hit ratio low?

The cache key probably includes all cookies, headers or query strings. Include only what changes the response.

Q. Invalidation or versioned file names?

Versioned names for assets (free, instant, easy rollback); invalidation for index.html and emergencies (1,000 free paths/month).

Try at home

  1. Create a custom cache policy that keys on the query string "page" only and test two pages.
  2. Add a /api/* behavior with CachingDisabled above the default and confirm Miss every time.

In short

  1. Behaviors match paths top to bottom; first match wins.
  2. Min/default/max TTL frame the origin's Cache-Control.
  3. Cache policy = key + TTL; origin request policy = extra data to origin.
  4. Keep the cache key small for a high hit rate.
  5. Version assets; invalidate only index.html.

Practice Tasks

About this scenario

Zurich Insurance Partners is a insurance business in Zurich. Anna Müller looks after its IT and cloud work. They count money in CHF and run their AWS resources in the eu-central-2 Region. In the tasks below you do real jobs for them using what this lesson teaches. All names, account IDs, IP addresses and numbers are made up for practice.

0 / 10

Easy List distributions

Why: Find the distribution ID and domain name.

What to do: List all CloudFront distributions.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Easy How many addresses in a /16?

Why: Picking a VPC size needs this count.

What to do: Zurich Insurance Partners plans the VPC 10.189.0.0/16. How many IP addresses does it hold in total?

How:
  1. Write down the numbers the task gives you.
  2. Work it out step by step on paper.
  3. Type only the final answer in the box.
  4. Click Check answer.

Easy Port for SSH

Why: Security group rules need the right port.

What to do: Which TCP port must the security group open for SSH?

How:
  1. Write down the numbers the task gives you.
  2. Work it out step by step on paper.
  3. Type only the final answer in the box.
  4. Click Check answer.

Medium Clear the CloudFront cache

Why: After a deploy, invalidate so visitors get the new files now, not after the TTL.

What to do: Invalidate all paths (/*) on distribution E2QWRUHAPOMQZL.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Hard Create a distribution from a config file

Why: The full config (origins, behaviors, certificate) is easiest to keep in JSON.

What to do: Create a CloudFront distribution from dist.json.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Hard Invalidate two paths

Why: Invalidating only what changed is cheaper and faster.

What to do: On E2QWRUHAPOMQZL, invalidate /index.html and /css/site.css.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Hard Bucket policy for CloudFront OAC

Why: With OAC, only your CloudFront distribution may read the private bucket.

What to do: Allow the service cloudfront.amazonaws.com to s3:GetObject on zurichinsure-site/*, only when aws:SourceArn equals arn:aws:cloudfront::131130276334:distribution/E2QWRUHAPOMQZL.

How:
  1. Start with { "Version": "2012-10-17", "Statement": [ ... ] }.
  2. In each statement write Effect, Action and Resource.
  3. Give only what the task needs (least privilege).
  4. Use double quotes and commas correctly. Click Check answer.

Hard Create an Origin Access Control

Why: OAC lets only CloudFront read your private S3 bucket.

What to do: Create an origin access control from oac.json.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Hard Request a free certificate for CloudFront

Why: CloudFront only uses ACM certificates from us-east-1. DNS validation renews automatically.

What to do: Request a certificate for zurichinsure.ch and www.zurichinsure.ch with DNS validation, in us-east-1.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Hard Make a CloudFront signed URL

Why: Signed URLs let only paying users watch a video, for a limited time.

What to do: Sign https://d111.cloudfront.net/course/intro.mp4 with key pair ID K2JCJMDEHXQW5F, private key private_key.pem, expiring 2026-12-31.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Revision, comparison and interview cards

Revise this lesson in a few minutes. Save the cards on your phone or download them as PNG files. The QR code on each card opens this lesson.

Revision card: Cache behaviors and order. A behavior = path pattern + origin + cache settings. Checked top to bottom; first match wins. Default (*) is always last. Put specific patterns above general ones.
Revision card: Cache behaviors and order · Download PNG
Revision card: Min, default and max TTL. Origin sends Cache-Control max-age. Min and max TTL clamp that value. Default TTL is used when the origin sends nothing. CachingOptimized: 1 s, 1 day, 1 year.
Revision card: Min, default and max TTL · Download PNG
Revision card: Invalidation vs versioned names. Invalidation drops paths from every edge. First 1,000 paths a month free, then $0.005 each. Versioned names (app.3f9a.js) need no invalidation. Invalidate index.html after deploy.
Revision card: Invalidation vs versioned names · Download PNG
Comparison: Cache policy vs Origin request policy. Cache policy: Sets TTLs and the cache key. Origin request policy: Adds headers, cookies or query strings sent to the origin on a miss.
Comparison: Cache policy vs Origin request policy · Download PNG
Comparison: Invalidation vs Versioned file names. Invalidation: Tell CloudFront to drop paths from all edges. Versioned file names: Give each new build new file names.
Comparison: Invalidation vs Versioned file names · Download PNG
Interview card: Your CloudFront hit ratio is low. What do you check?. The cache key: extra cookies, headers or query strings. TTLs and the origin Cache-Control headers. Move values the origin needs to an origin request policy.
Interview card: Your CloudFront hit ratio is low. What do you check? · Download PNG

More cards: Ravi Sir's Cards.