This chapter covers CloudFront cache behaviors and TTL (Time-to-Live) settings, a core topic for the SAA-C03 exam under Domain 3: High Performance, Objective 3.4. Understanding how CloudFront determines how long to cache objects at edge locations is critical for optimizing performance, reducing origin load, and controlling content freshness. Expect 5-10% of exam questions to involve cache behaviors, TTL precedence, or related troubleshooting scenarios. You will learn the exact mechanism of TTL evaluation, how to configure cache behaviors, and how to avoid common misconfigurations that lead to stale content or excessive origin fetches.
Jump to a section
Imagine a public library with a very strict due-date policy. The library (CloudFront edge location) stores popular books (cached objects) for patrons (users). Each book has a due date set by the publisher (origin server) via a sticker on the cover (Cache-Control: max-age). The library's own policy (CloudFront minimum TTL) says no book can be due back in less than 1 hour, even if the publisher says 5 minutes. Another policy (CloudFront default TTL) applies if the publisher forgets to put a sticker. The library also has a special shelf (custom TTL) for books from certain publishers (specific paths/behaviors) where the librarian (you) sets a different due date. When a patron asks for a book, the librarian checks if it's on the shelf and not overdue. If overdue, the librarian calls the publisher to get a fresh copy (origin fetch), and the publisher may say 'this copy is good for 2 hours' (new max-age). If the book is not overdue, the librarian hands it over immediately (cache hit). The librarian also respects a special instruction: if the publisher says 'no caching' (Cache-Control: no-cache, private), the librarian must not keep the book at all. But the library's own override policy (CloudFront maximum TTL) can force the librarian to keep a book for up to 7 days, ignoring the publisher's instructions. This models CloudFront's TTL precedence: the effective TTL is clamped between the minimum and maximum TTL, with the origin's Cache-Control max-age or the default TTL used as the base, depending on presence and configuration.
What Are CloudFront Cache Behaviors?
CloudFront cache behaviors allow you to define different caching rules for different URL path patterns within a single distribution. Each behavior specifies:
Path pattern (e.g., /images/*, /api/*, default (*))
Origin to forward requests to
Viewer protocol policy (HTTP or HTTPS)
Allowed HTTP methods
Whether to forward query strings, cookies, or headers
TTL settings: Minimum TTL, Maximum TTL, and Default TTL
Whether to compress objects automatically
You can have up to 25 cache behaviors per distribution (default plus 24 additional). The default behavior always applies to requests that don't match any other pattern. Patterns are evaluated in order; the first match wins.
How TTL Works in CloudFront
TTL (Time-to-Live) determines how long an object remains in CloudFront's edge cache before CloudFront checks with the origin for a newer version. The effective TTL is calculated using three values:
- Origin Cache-Control headers: The max-age directive (in seconds) sent by the origin. If present, this is the base TTL.
- CloudFront Default TTL: Used when the origin does not send Cache-Control: max-age or Expires headers. Default is 24 hours (86400 seconds) for web distributions, 0 for RTMP.
- CloudFront Minimum TTL: The minimum time CloudFront will cache an object, regardless of origin headers. Default is 0.
- CloudFront Maximum TTL: The maximum time CloudFront will cache an object, regardless of origin headers. Default is 365 days (31536000 seconds).
The effective TTL is determined as follows:
1. If the origin sends Cache-Control: max-age=NNN, the base TTL is NNN seconds.
2. If the origin sends Cache-Control: s-maxage=NNN, that overrides max-age for shared caches (including CloudFront).
3. If the origin sends Expires header (but no max-age), CloudFront converts it to TTL.
4. If the origin sends no caching directives, CloudFront uses the Default TTL.
5. The effective TTL is then clamped: max(Minimum TTL, min(base TTL, Maximum TTL)).
Important: If the origin sends Cache-Control: no-cache, no-store, or private, CloudFront will not cache the object by default, regardless of TTL settings. However, you can override this by setting a Minimum TTL greater than 0, which forces CloudFront to cache the object for at least that duration. This is a common exam trap.
Key Default Values and Timers
Default TTL (web): 24 hours (86400 seconds)
Minimum TTL (web): 0 seconds
Maximum TTL (web): 365 days (31536000 seconds)
Default TTL (RTMP): 0 seconds (no caching)
Origin response timeout: 30 seconds (time to wait for origin to respond)
Origin keep-alive timeout: 5 seconds
Error caching minimum TTL: 300 seconds (5 minutes) – CloudFront caches error responses (4xx, 5xx) for at least this long to reduce origin load.
Configuring Cache Behaviors
You configure cache behaviors in the CloudFront distribution settings. For each behavior, you can set:
- Path Pattern: e.g., *.jpg, /api/*, admin/*. Patterns support wildcards (*) and can be simple prefixes.
- Origin: Choose from existing origins or create a new one.
- Viewer Protocol Policy: HTTP and HTTPS, Redirect HTTP to HTTPS, or HTTPS Only.
- Allowed HTTP Methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE.
- Cached HTTP Methods: GET and HEAD only (by default). You can also cache OPTIONS responses.
- Cache Based on Selected Headers: None (recommended for performance), Whitelist (specify headers to include), or All (use with caution).
- Cache Based on Selected Query Strings: None, All, or Whitelist.
- Cache Based on Selected Cookies: None, All, or Whitelist.
- Object Caching: Use Origin Cache Headers, Customize, or Use Default (if you want to set explicit TTL values).
- Minimum TTL: 0–31536000 seconds
- Maximum TTL: 0–31536000 seconds
- Default TTL: 0–31536000 seconds
- Compress Objects Automatically: Yes/No (if origin sends compressed or not).
- Lambda@Edge: Associate a Lambda function to run on viewer request/response or origin request/response.
Verification Commands
You can test cache behavior using curl to inspect headers:
curl -I https://d123.cloudfront.net/image.jpgLook for:
- X-Cache: Hit from cloudfront (cached) or Miss from cloudfront (not cached)
- Age: how long the object has been in cache (in seconds)
- Cache-Control: max-age=3600 (origin set TTL)
- Via: 1.1 abc123.cloudfront.net:80 (proxy info)
To force a cache invalidation, use the AWS CLI:
aws cloudfront create-invalidation --distribution-id E123456 --paths "/image.jpg" "/images/*"Invalidation paths are case-sensitive and must start with /. You can invalidate up to 3000 objects per month free; additional batches cost $0.005 per path.
Interaction with Related Technologies
Origin Shield: A centralized caching layer that reduces load on origin and improves cache hit ratio. It sits between CloudFront edge locations and the origin, aggregating requests.
Lambda@Edge: Can modify request/response headers, including Cache-Control, to dynamically adjust TTL.
S3 as Origin: By default, S3 objects don't have Cache-Control headers. You must set them via object metadata (e.g., Cache-Control: max-age=86400). If not set, CloudFront uses Default TTL (24 hours).
Elastic Load Balancer (ALB/NLB) as Origin: The ALB can add Cache-Control headers based on your application logic.
Web Application Firewall (WAF): Can be associated with CloudFront to filter requests before they reach the cache.
CloudFront Functions: Lightweight functions for header manipulation at edge, can set cache keys.
Precedence and Overrides
The order of precedence for TTL is:
1. Origin's Cache-Control: s-maxage (if present)
2. Origin's Cache-Control: max-age (if present)
3. Origin's Expires header (if present, and no max-age)
4. CloudFront Default TTL (if no origin caching headers)
5. The result is then clamped by Minimum TTL and Maximum TTL.
Trap: If you set Minimum TTL to 0, and origin sends Cache-Control: no-cache, CloudFront will not cache the object (effective TTL = 0). If you set Minimum TTL to 60, CloudFront caches it for at least 60 seconds even if origin says no-cache.
Performance Considerations
Shorter TTLs increase origin load but reduce staleness.
Longer TTLs improve cache hit ratio and reduce latency.
Use different cache behaviors for static vs. dynamic content.
For API responses, consider using Cache-Control: no-cache or very short TTLs (e.g., 1 second).
For media files, use long TTLs (e.g., 1 year) and versioning (e.g., /images/v2/logo.png) to allow cache invalidation by changing URL.
Use Origin Shield to reduce origin load further.
User requests object via CloudFront URL
A user's browser sends an HTTP GET request to the CloudFront distribution domain (e.g., d123.cloudfront.net/image.jpg). CloudFront's edge location nearest to the user receives the request. It first determines which cache behavior applies by matching the URL path against the configured path patterns. The first match wins; if no match, the default behavior is used.
CloudFront checks edge cache for object
CloudFront looks up the object in its local cache at that edge location. The cache key is based on the URL, plus any query strings, cookies, or headers that are whitelisted for that behavior. If the object is present and has not expired (based on effective TTL), a cache hit occurs. CloudFront returns the object immediately with the header `X-Cache: Hit from cloudfront`. The Age header indicates how long the object has been in cache.
Cache miss: CloudFront forwards request to origin
If the object is not in cache or has expired, CloudFront forwards the request to the origin (e.g., S3 bucket, ALB, or custom HTTP server). CloudFront adds headers like `X-Forwarded-For` (client IP), `X-Amz-Cf-Id` (unique request ID), and `Via`. The origin processes the request and returns a response with HTTP status code, headers, and body.
CloudFront evaluates origin response headers for caching
CloudFront examines the response headers from the origin, specifically `Cache-Control` and `Expires`. It extracts `s-maxage` (if present, highest priority), then `max-age`, then `Expires`. If none are present, it uses the Default TTL for that behavior. The effective TTL is then clamped between the Minimum TTL and Maximum TTL. If the origin returns `Cache-Control: no-cache` or `no-store`, and Minimum TTL is 0, CloudFront does not cache the object.
CloudFront caches object and serves to user
CloudFront stores the object in its edge cache with the effective TTL. It then returns the response to the user, including the `X-Cache: Miss from cloudfront` header (or `Hit` if it was a cache hit). Subsequent requests for the same object within the TTL will result in cache hits. If the object is invalidated via a CloudFront invalidation request, it is removed from all edge caches immediately.
Scenario 1: E-commerce Platform with Mixed Content
An online retailer uses CloudFront to serve both static assets (product images, CSS, JavaScript) and dynamic API responses (product availability, cart). The static assets are stored in S3 and have long Cache-Control headers (max-age=31536000, 1 year). The API runs on EC2 behind an ALB and returns Cache-Control: no-cache for cart data and max-age=60 for product listings. The CloudFront distribution has two cache behaviors:
Path pattern /static/* with Minimum TTL=0, Maximum TTL=31536000, Default TTL=86400 (uses origin headers).
Path pattern /api/* with Minimum TTL=0, Maximum TTL=60, Default TTL=0 (forces short TTL for API).
This setup ensures product images are cached for a year, reducing load on S3. API responses are cached only for up to 60 seconds, balancing freshness and performance. The problem arises when the API accidentally returns Cache-Control: max-age=3600 due to a bug; CloudFront would cache that for up to 3600 seconds, causing stale data. To prevent this, the team sets Maximum TTL=60 for the API behavior, overriding any larger origin value.
Scenario 2: Media Streaming Service with Origin Shield
A video streaming service uses CloudFront to deliver HLS segments (ts files). Each segment is about 10 seconds long and is stored in S3 with Cache-Control: max-age=86400 (24 hours). The service has millions of users worldwide. To reduce origin load, they enable Origin Shield in the US East (N. Virginia) region. Origin Shield acts as a central cache that aggregates requests from all edge locations. When a segment is not in an edge cache, the edge forwards the request to Origin Shield. If Origin Shield has it, it serves from there; otherwise, it fetches from S3. This reduces the number of requests to S3 by 80%. The team sets Minimum TTL to 0, allowing origin headers to control caching. They also use CloudFront Functions to add a custom header for access control.
Scenario 3: News Website with Frequent Content Updates
A news website updates articles frequently. They use CloudFront with a custom origin (WordPress on EC2). The origin sets Cache-Control: max-age=300 (5 minutes) for article pages. However, breaking news requires immediate propagation. They use CloudFront invalidations to purge specific article URLs when updated. They also set a Minimum TTL of 0 to ensure no object is cached longer than the origin intends. For static assets like logos and CSS, they use a separate cache behavior with a long TTL (1 year) and versioning in the URL (e.g., /assets/logo.v2.png). This way, they can update assets by changing the URL without invalidating the old one. Misconfiguration: If they accidentally set Minimum TTL to 3600 for the default behavior, even articles with max-age=300 would be cached for at least 1 hour, causing stale headlines.
SAA-C03 Exam Focus: CloudFront Cache Behaviors and TTL
Objective 3.4: Design high-performing and scalable architectures. Sub-objectives include caching strategies.
Common Wrong Answers: 1. Choosing 'CloudFront always uses the origin's Cache-Control header' – Wrong. CloudFront clamps the TTL between Minimum and Maximum TTL, and can override no-cache with a positive Minimum TTL. 2. Thinking that setting Minimum TTL to 0 means no caching – Wrong. Minimum TTL=0 means CloudFront will cache for 0 seconds only if origin says no-cache; if origin says max-age=3600, it caches for 3600. 3. Believing that CloudFront caches error responses for the same TTL as successful responses – Wrong. CloudFront caches 4xx/5xx errors for Error Caching Minimum TTL (default 300 seconds) regardless of other TTL settings. 4. Confusing Default TTL with Minimum TTL – Default TTL applies only when origin sends no caching headers; Minimum TTL is a floor for all caching.
Specific Numbers and Values:
Default TTL: 86400 seconds (24 hours)
Minimum TTL: 0 seconds
Maximum TTL: 31536000 seconds (365 days)
Error Caching Minimum TTL: 300 seconds (5 minutes)
Max cache behaviors: 25
Invalidation cost: first 3000 paths free per month, then $0.005 per path
Origin response timeout: 30 seconds
Origin keep-alive timeout: 5 seconds
Edge Cases and Exceptions:
If origin sends both max-age and s-maxage, CloudFront uses s-maxage.
If origin sends Expires header but no Cache-Control, CloudFront uses Expires.
If origin sends Cache-Control: private, CloudFront does not cache by default (but can be overridden with Minimum TTL).
CloudFront does not cache responses with Set-Cookie header unless the cache behavior is configured to forward cookies.
For POST/PUT/DELETE requests, CloudFront forwards them to origin and does not cache the response (only GET/HEAD/OPTIONS can be cached).
How to Eliminate Wrong Answers:
If a question asks about making content available immediately after an update, look for 'invalidation' or 'versioned URLs'.
If a question involves reducing origin load for static content, consider long TTLs and Origin Shield.
If a question involves dynamic content, consider short TTLs or no-cache with Lambda@Edge for custom logic.
CloudFront effective TTL = clamp(origin TTL, Minimum TTL, Maximum TTL).
Default TTL (86400s) applies only when origin provides no caching headers.
Minimum TTL can override 'no-cache' from origin if set > 0.
Maximum TTL caps origin's max-age; default is 365 days.
Error responses (4xx/5xx) are cached for at least 300 seconds (Error Caching Minimum TTL).
CloudFront caches only GET, HEAD, and OPTIONS responses.
Invalidation paths are case-sensitive and start with '/'.
Origin Shield reduces origin load by aggregating requests at a regional cache.
Use separate cache behaviors for static (long TTL) and dynamic (short TTL) content.
Versioned URLs (e.g., /images/v2/logo.png) avoid invalidation costs.
These come up on the exam all the time. Here's how to tell them apart.
CloudFront Default TTL
Used only when origin sends no Cache-Control or Expires headers.
Default value is 86400 seconds (24 hours).
Can be set per cache behavior.
Has no effect if origin sends caching headers.
Example: If origin does not set max-age, CloudFront caches for 24 hours.
CloudFront Minimum TTL
Always applies as a lower bound on effective TTL.
Default value is 0 seconds.
Can be set per cache behavior.
Overrides origin's no-cache directive if set > 0.
Example: If Minimum TTL=60, CloudFront caches for at least 60 seconds even if origin says no-cache.
Mistake
CloudFront always respects the origin's Cache-Control: max-age exactly as-is.
Correct
CloudFront clamps the TTL between Minimum TTL and Maximum TTL. If max-age is below Minimum TTL, CloudFront uses Minimum TTL; if above Maximum TTL, it uses Maximum TTL.
Mistake
Setting Minimum TTL to 0 disables caching entirely.
Correct
Minimum TTL=0 means CloudFront will cache for 0 seconds only if the origin sends no-cache or no-store. If the origin sends max-age=3600, CloudFront caches for 3600 seconds.
Mistake
CloudFront caches all HTTP methods (GET, POST, PUT, etc.).
Correct
CloudFront only caches responses to GET, HEAD, and OPTIONS requests. POST, PUT, PATCH, DELETE requests are forwarded to the origin and not cached.
Mistake
Default TTL and Minimum TTL are the same thing.
Correct
Default TTL applies only when the origin does not send any caching headers (no Cache-Control or Expires). Minimum TTL is a floor that applies regardless of origin headers.
Mistake
CloudFront caches error responses (4xx/5xx) for the same duration as successful responses.
Correct
CloudFront caches error responses for the Error Caching Minimum TTL (default 300 seconds), regardless of the TTL settings for successful responses.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
Default TTL is used only when the origin does not send any Cache-Control or Expires headers. It sets the caching duration in that case. Minimum TTL is a floor that applies to all objects, regardless of origin headers. If the origin sends a max-age lower than Minimum TTL, CloudFront uses Minimum TTL. If the origin sends no-cache, CloudFront will cache for Minimum TTL seconds if Minimum TTL > 0. Exam tip: Default TTL is the fallback; Minimum TTL is the safety net.
Set the origin to return `Cache-Control: no-cache, no-store, private` and set CloudFront's Minimum TTL to 0 for that cache behavior. Additionally, set Maximum TTL to 0 to ensure no caching. However, note that CloudFront may still cache error responses for 300 seconds. To completely avoid caching, you can also use Lambda@Edge to modify the response headers.
CloudFront uses `s-maxage` because it is intended for shared caches (like CloudFront). The `max-age` is ignored for caching decisions. Exam tip: If you see `s-maxage` in an origin response, CloudFront will use that value as the base TTL, subject to clamping.
Use the AWS Management Console, CLI, or SDK to create an invalidation. Specify the paths (e.g., `/images/*`). Invalidation is case-sensitive and must start with `/`. The first 3000 paths per month are free; additional paths cost $0.005 each. Invalidations propagate to all edge locations within minutes.
Yes, but you must configure the cache behavior to forward query strings. You can choose to forward all query strings (each unique combination creates a separate cache entry) or whitelist specific query strings. Forwarding all query strings can reduce cache hit ratio. Exam tip: For APIs, consider whitelisting only the query parameters that affect the response.
It is the minimum duration (default 300 seconds) that CloudFront caches error responses (4xx and 5xx) from the origin. This prevents the origin from being overwhelmed by repeated requests for failing objects. If you need to clear error caches sooner, you can invalidate the paths or reduce this value (minimum 0).
Origin Shield is an additional caching layer that sits between CloudFront edge locations and the origin. It aggregates requests from multiple edges, increasing cache hit ratio and reducing origin load. It does not change TTL behavior; it simply caches objects at a regional level. Use it for high-traffic workloads with many edge locations.
You've just covered CloudFront Cache Behaviors and TTL — now see how well it sticks with free SAA-C03 practice questions. Full explanations included, no account needed.
Done with this chapter?