Guides

Performance guide

CDN Caching Explained: What to Cache, What Not to Cache

A safe caching policy starts with the response's audience, freshness, cache key, and invalidation plan.

A CDN cache stores eligible HTTP responses at edge locations so later requests can be answered closer to users and without a trip to the origin. Cache static assets aggressively when their URLs are versioned, cache public content for a deliberate freshness window, and keep personalized or sensitive responses out of shared caches. The difficult part is not turning caching on; it is proving that the same cached response is safe for every request that can receive it.

How a CDN cache decides

For a request, the CDN calculates a cache key, looks for a stored response, and checks whether that response is fresh and valid for the request. A hit can avoid origin latency. A miss fetches the response, applies cacheability rules, and may store it for later requests. A stale response may be revalidated with the origin using ETag or Last-Modified, or it may be served under an explicitly permitted stale policy.

The URL is often the minimum cache-key input, but real systems may also vary by host, query string, method, language, encoding, device hints, cookies, authorization, or selected request headers. Every extra dimension can fragment the cache. Every omitted dimension can risk serving the wrong representation.

Cache the representation, not the request by accident

Before caching a response, write down which users may receive it, what makes two representations different, how long it may be fresh, and how an update reaches every edge.

What to cache

Versioned static assets

Cache hashed JavaScript, CSS, fonts, icons, and immutable media for a long time. A generic policy is:

Cache-Control: public, max-age=31536000, immutable

The long lifetime is safe only if a changed file receives a new URL. Do not overwrite /app.js while browsers and edges are allowed to keep the old bytes for a year. Use a content hash, release number, or another versioned URL and remove old versions according to your deployment policy.

Public images and media

Images, video segments, posters, and downloadable public documents are often good CDN candidates. Choose a freshness window appropriate to editorial updates, support range requests where needed, and vary image representations intentionally by width, format, or device. Avoid creating a unique cache key for every incidental request header. Adaptive image delivery shows why right-sized variants matter for both bytes and speed.

Public HTML and API responses

Public pages and read-only API responses can be cached when their output is not personalized and their freshness is acceptable. Use a short TTL, conditional revalidation, or stale-while-revalidate for content that can tolerate a small freshness window. A CDN such as Cloudflare or Fastly may expose equivalent edge TTL and purge controls, but the origin policy and the provider's effective rules must be tested together.

Example:

Cache-Control: public, max-age=60, stale-while-revalidate=30
ETag: "article-42-v7"

The stale window allows a cache to serve the previous response while it revalidates when the implementation supports that behavior. Use it only when serving slightly old content is acceptable. If browser and shared-cache lifetimes must differ, use s-maxage as a separate policy and verify how the selected CDN handles its interaction with stale directives.

What not to cache in a shared CDN

Keep account pages, order history, carts, checkout, payment responses, private dashboards, and responses containing personal data out of shared caches. A safe baseline for sensitive content is:

Cache-Control: private, no-store

Use no-store when the response must not be stored. If a response may be stored in a private browser cache but must not be reused by a shared CDN, private is the important directive. no-cache has a different meaning: it allows storage but requires validation before reuse.

Be careful with responses that set cookies. A response that includes a session or personalization cookie should not become a shared object merely because an edge rule says "cache HTML." Check Authorization, Cookie, Set-Cookie, and Vary behavior explicitly. If you have a public shell and private data, cache those layers separately and make the boundary obvious.

Do not cache state-changing requests by default. POST, PUT, PATCH, and DELETE require application-specific semantics and invalidation. Most CDN caching is designed around safe retrievals such as GET and HEAD.

Design the cache key carefully

Normalize query parameters that do not change content, such as tracking parameters, but do not remove parameters that select a product, locale, filter, or representation. Decide whether parameter order should matter. If the response changes by language or encoding, use a correct Vary policy or an equivalent provider configuration. Make sure the CDN actually honors the headers you send; some products have provider-specific defaults.

Avoid varying on the full Cookie header. It creates many low-hit-rate objects and can mix application state into edge behavior. Extract only the signal needed for a public variant, or bypass shared caching when the response is truly personalized.

If a response is negotiated by Accept, Accept-Encoding, or client hints, validate the complete path from origin to edge to browser. A response that is correct for one device or language is not correct for every cache key.

Invalidation is part of the design

A TTL is not a purge strategy. Decide how urgent corrections, product availability, security changes, and releases invalidate cached objects. Use versioned URLs for assets, targeted purges for known content, and a documented broader purge procedure for incidents. Understand whether a purge is global, asynchronous, soft, or provider-specific. Test what a user sees during propagation.

Keep validators such as ETag or Last-Modified on responses that can be revalidated. A 304 Not Modified response can refresh cache metadata without transferring the full body. Monitor hit ratio, origin requests, stale responses, purge completion, and cache errors rather than treating a high hit ratio as the only success measure.

Common mistakes

Do not equate a cache hit with a correct response. Do not cache all HTML because static assets are safe. Do not use no-cache when you mean no-store. Do not use a year-long TTL for mutable URLs. Do not ignore query strings or cookies in the cache key. Do not apply stale-if-error to content that becomes dangerous or misleading when old. Do not assume a Cloudflare or Fastly dashboard setting has the same precedence as origin headers without checking its documentation and response headers.

Validation checklist

Test a cold miss, a warm hit, a stale revalidation, a purged object, and an origin error. Repeat for anonymous, authenticated, localized, mobile, and cookie-bearing requests. Inspect Cache-Control, Age, ETag, Last-Modified, Vary, Set-Cookie, status, content encoding, cache status, and response body. Confirm that an update becomes visible within the promised window and that sensitive data never appears in a shared object.

For directive-by-directive policy examples, read How to configure Cache-Control. For the network layer around the cache, see Optimi's managed CDN guide and managed DNS. For a broader site-speed sequence, use the slow-website performance checklist.

There are only two hard things in Computer Science: cache invalidation and naming things.

Make your CDN cache safe and useful

Talk to our team about cache keys, freshness, purge behavior, and origin protection for your traffic.

Get Started