Skip to content

CloudFront cache behaviors

A cache behaviour tells CloudFront how to handle requests whose path matches a pattern: which origin to use, what to cache, and which edge functions to run.

  • Each behaviour is bound to a path pattern such as /images/* or *.jpg.
  • CloudFront evaluates behaviours in the order they are listed and applies the first match. Order is significant: a * behaviour placed before /api/* swallows every API request.
  • The default behaviour, *, catches everything unmatched and is always evaluated last.
  • Target origin, and the origin protocol policy used to reach it
  • Viewer protocol policy — allow HTTP, redirect HTTP to HTTPS, or require HTTPS
  • Allowed HTTP methods, and which of them are cached
  • Cache policy: minimum, maximum and default TTL
  • Cache key: which headers, cookies and query strings form part of the key
  • Origin request policy: which headers, cookies and query strings are forwarded to the origin, whether or not they are in the cache key
  • Compression (gzip and Brotli)
  • Function associations — CloudFront Functions or Lambda@Edge
  • Field-level encryption, and whether signed URLs or cookies are required

The cache key and the origin request policy are separate on purpose. Forwarding a header to the origin without adding it to the cache key lets the origin see it while keeping one cached object; adding it to the cache key creates one cached object per distinct value. Getting this backwards is the usual cause of a cache hit ratio that will not rise.

{
"PathPattern": "/images/*",
"TargetOriginId": "S3-my-bucket",
"ViewerProtocolPolicy": "redirect-to-https",
"AllowedMethods": ["GET", "HEAD"],
"CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6",
"OriginRequestPolicyId": "88a5eaf4-2fd4-4709-b370-b4c650ea3fcf"
}

The two policy IDs are AWS managed policies — CachingOptimized and CORS-S3Origin respectively. Managed policies cover most cases; write a custom policy only when none of them fits.

  1. Different caching for different content types: long TTLs for versioned assets, no caching for an API.
  2. Separating API traffic from static delivery, with different origins and methods.
  3. Requiring signed URLs on one path prefix and leaving the rest public.
  4. Routing by content type to different origins — S3 for assets, a load balancer for the application.
  5. Custom error responses for particular paths.