Skip to content

CloudFront for dynamic content

CloudFront is usually described as a cache, which makes it easy to assume it has nothing to offer for content that cannot be cached. It does. Most of the latency saving on a dynamic request comes from where the connection terminates and how it travels, not from a cache hit.

By default CloudFront forwards a request it cannot serve from cache to the origin. Set the cache behaviour’s TTLs to zero — or attach the managed CachingDisabled cache policy — and every request goes to the origin, which is the correct configuration for genuinely dynamic responses.

The request still benefits:

  • The TLS handshake happens at the edge. The viewer completes its handshake with a nearby edge location instead of with an origin that may be thousands of kilometres away, removing several round trips from the first request.
  • The edge-to-origin connection is already open. CloudFront maintains a pool of persistent connections to each origin and reuses them, so the origin leg usually costs no handshake at all.
  • The traffic rides the AWS backbone. From the edge onward the request travels AWS’s network rather than the public internet, which is both faster and more predictable.
  • Compression is available, but not automatic. Edge compression needs the behaviour’s Compress objects automatically setting on and a cache policy with Gzip and Brotli enabled — which the managed CachingDisabled policy does not have. For a dynamic behaviour, either compress at the origin and return Content-Encoding, or use a custom cache policy with every TTL at zero and compression enabled. CloudFront compresses only bodies between 1,000 and 10,000,000 bytes.

Configuring a behaviour for dynamic content

Section titled “Configuring a behaviour for dynamic content”

Use cache policies and origin request policies rather than the legacy ForwardedValues settings. The two do different jobs, and separating them is the point:

  • The cache policy defines the cache key — which headers, cookies and query strings make two requests different. For dynamic content, the managed CachingDisabled policy sets minimum, default and maximum TTL to zero.
  • The origin request policy defines what is forwarded to the origin without affecting the cache key. The managed AllViewer policy forwards all viewer headers, cookies and query strings, which is what an application origin generally expects.

Forwarding everything through the cache key instead — the old ForwardedValues approach with Headers: ["*"] and Cookies: all — works, but it collapses the cache hit ratio for any behaviour that could have cached something, which is why AWS separated the two concepts.

  • Origin failover. An origin group with a primary and a secondary origin fails over on configured status codes, which is cheap resilience for a dynamic endpoint.
  • Real-time logs. Standard access logs are delivered in batches; real-time logs are the ones you want when diagnosing a live latency problem.
  • AWS WAF and AWS Shield. Attaching a web ACL at the distribution puts filtering in front of the origin rather than on it.
  • Price class. If the audience is regional, restricting the price class removes edge locations you are paying for and not using.

Origin Shield adds a caching layer in a chosen Region in front of the origin, and it is valuable when several regional edge caches would otherwise each fetch the same object. AWS is explicit that it is not a good fit for dynamic content proxied to the origin, content with low cacheability, or content that is requested infrequently — for those, it adds a hop and a charge without a corresponding hit. Enable it for a cacheable behaviour with a geographically spread audience, in the Region with the lowest latency to the origin; leave it off for the dynamic behaviours.