Loading...

Case studies

Case study: a news site's cache header setup

A high-traffic Turkish sports news site manages caching from its own origin instead of the panel. Four content tiers, four different Cache-Control headers — all verifiable from the outside.

Back to Platform Help
What this page covers

The live response headers from a real account, and why each one was chosen. The customer isn't named; every header shown here is written so you can verify it on your own site by running the same command.

Four tiers, four different lifetimes

A single cache lifetime doesn't work for a news site: the homepage changes by the minute, the logo doesn't change for years. This account splits content by how fast it changes.

Content Header sent by the origin Why
Homepage public, max-age=30, s-maxage=30, stale-while-revalidate=60 Breaking news refreshes every 30 seconds; when it expires the visitor shouldn't have to wait — the edge serves the stale copy while it revalidates in the background.
Section and listing pages public, max-age=300, s-maxage=300, stale-while-revalidate=600 Category pages don't change as often as the homepage. Five minutes isn't a delay the editorial team would notice, and it cuts the load on the edge considerably.
Versioned static file public, max-age=31536000, s-maxage=31536000, immutable The filename carries a version, so its content never changes. immutable stops the browser from revalidating even before max-age expires.
Optimized image max-age=31536000 + public on a separate line This line is written by the edge, not the origin — when Image Optimization is on for a rule, the header is regenerated unconditionally.

Setting up the same layout on your own site

1

Split content by how fast it changes

Decide which path changes how often before you decide on lifetimes — the lifetime is a consequence of that decision.

  • Changes within minutes: homepage, live scores, breaking-news feed
  • Changes within hours: category pages, archive listings
  • Never changes: CSS, JS, fonts, logo — anything whose filename carries a version
  • Personal: logged-in pages, cart, account — these aren't cached and shouldn't be
2

Send the headers from your origin

Your application or web server sends the header. You don't need to enter a lifetime in the panel — the two approaches don't work together on the same rule.

  • s-maxage is for the shared cache (the CDN), max-age is for the browser; you can give them different values
  • stale-while-revalidate means the visitor doesn't wait when the lifetime expires — the stale copy is served while a fresh one is fetched in the background
  • immutable should only be sent when the filename is versioned; on an unversioned file it leaves the browser stuck with a year-old copy
3

Let the rule defer to the origin

In Delivery Rules, that path's rule needs Use browser cache time turned on and Cache Expire Time left empty.

  • If you enter a lifetime, the origin's headers are ignored on that rule and the header sent to the browser gets rewritten too
  • You can split rules by path: one rule for static files, another for pages
4

Measure, then expand

Try it on a single path first. Once you see the header you expect coming back and you're getting a HIT, move on to the other tiers.

How to see that it's working

Everything shows up in the response headers — you don't need to check the panel. Request the same URL twice:

curl -sI https://your-site.com/a-page | grep -iE "cache-control|x-proxy-cache-mt"
  • X-Proxy-Cache-MT: MISS is normal on the first request — the content is being cached right then. The second request should return HIT.
  • STALE is not an error: it means stale-while-revalidate is doing its job — the visitor gets the old copy while a fresh one is fetched in the background.
  • If you see BYPASS, you're almost certainly logged into the site — a session cookie deliberately skips the cache. Try again in a private/incognito window.
  • If the Cache-Control that comes back is different from what you sent, a fixed lifetime has been entered on that rule.
  • If you also want to see what the origin sent, turn on origin diagnostic headers for the rule; X-Upstream-CacheControl shows what the origin said, Cache-Control shows what the visitor sees.

Three things that make the right header useless

  • A response that sends Set-Cookie is never cached. It doesn't matter how correct the Cache-Control is. This is the most common reason a cache never warms up: the application is setting a session cookie on every request.
  • With Image Optimization on for a rule, images are kept for 365 days and the origin's header is ignored. If you want to manage images yourself, turn this setting off for that rule.
  • Don't send immutable on a file that isn't versioned. If the filename doesn't change, the browser keeps using the stale copy for a year, and a CDN purge won't fix that — purge only clears the edge, not the visitor's disk.

Next