Cloudflare CDN in Practice: Cache What Matters, Avoid What Breaks

Cloudflare CDN in Practice: Cache What Matters, Avoid What Breaks

Cloudflare can make a site feel “instant” by serving content from the edge (near your users) instead of hitting your origin server on every request. The trick is caching the right things (static assets, public pages, API responses that are safe) while not caching user-specific or rapidly-changing content.

This hands-on guide walks you through a practical setup for junior/mid developers: how to verify caching, set cache headers correctly, create safe cache rules, and use a Cloudflare Worker for “CDN-style caching” of API responses.

1) Start by measuring: Is Cloudflare caching anything?

The fastest way to debug is to check response headers. Cloudflare commonly returns CF-Cache-Status with values like HIT, MISS, BYPASS, or EXPIRED (you’ll see variations depending on configuration and revalidation).

curl -I https://example.com/assets/app.css

Look for:

  • CF-Cache-Status: HIT → served from Cloudflare cache
  • CF-Cache-Status: MISS → fetched from origin and may be cached next time
  • Cache-Control → your origin’s caching instructions

Also test with a “public page” and a “logged-in page” to ensure you’re not accidentally caching personalized HTML.

2) Set sane caching headers at the origin (the “source of truth”)

Cloudflare can cache even when your origin doesn’t, but you’ll get the most predictable results when your origin sends correct Cache-Control headers. MDN’s Cache-Control reference is the best quick refresher. :contentReference[oaicite:0]{index=0}

Here are practical defaults:

  • Static assets (CSS/JS/images): long cache + immutable filenames
  • HTML: short cache or “must revalidate” unless you’re doing full-page caching carefully
  • User-specific pages: private, no-store (or at least private)

2a) Example: Express.js static assets with long-lived caching

If your build outputs hashed filenames (app.3f2c9a.js), you can safely cache them for a year.

// server.js (Express) import express from "express"; import path from "path"; const app = express(); // Cache immutable build assets for 1 year app.use( "/assets", express.static(path.join(process.cwd(), "public/assets"), { setHeaders(res) { res.setHeader("Cache-Control", "public, max-age=31536000, immutable"); }, }) ); // For HTML (SSR or static), keep it shorter by default app.get("/", (req, res) => { res.setHeader("Cache-Control", "public, max-age=60, stale-while-revalidate=300"); res.send("<!doctype html><h1>Hello</h1>"); }); app.listen(3000, () => console.log("Listening on http://localhost:3000"));

Why stale-while-revalidate? It lets caches serve a slightly stale page while they refresh it in the background, improving perceived speed. Cloudflare’s behavior here depends on the header being present. :contentReference[oaicite:1]{index=1}

2b) Example: Nginx headers for static files

# nginx.conf (inside a server block) location /assets/ { add_header Cache-Control "public, max-age=31536000, immutable"; try_files $uri =404; } # HTML: modest caching location / { add_header Cache-Control "public, max-age=60, stale-while-revalidate=300"; try_files $uri /index.html; }

3) Use Cloudflare Cache Rules (safely)

Cloudflare’s modern approach is Cache Rules, which let you match requests (by path, hostname, headers, etc.) and apply caching behavior. Cloudflare provides official docs and dashboard steps for creating these rules. :contentReference[oaicite:2]{index=2}

Two very common patterns:

  • Cache static assets aggressively (often already handled by headers, but rules can enforce consistency)
  • Cache selected HTML routes (marketing pages, docs, landing pages), while excluding auth/admin

3a) “Cache Everything” without breaking logged-in users

Cloudflare documents a “Cache Everything” style rule and warns it can serve the wrong HTML if you cache dynamic/user-specific pages. The key is adding exclusions so those URLs (and often certain cookies) don’t match. :contentReference[oaicite:3]{index=3}

A practical approach:

  • Rule 1 (Bypass): if path starts with /admin, /account, /checkout, /api → bypass cache
  • Rule 2 (Cache): if path matches /, /docs/*, /blog/* → cache (edge TTL 5–30 minutes)

If your app sets a session cookie like session or auth, consider bypassing caching when that cookie exists (depending on your app). Your goal: public visitors can be cached; authenticated sessions should not.

4) Cache API responses at the edge with a Cloudflare Worker

Sometimes you want to cache expensive API responses (e.g., public product lists, search suggestions) even if your origin can’t easily do it. Cloudflare Workers can cache responses using the Cache API (caches.default) and/or by configuring caching in fetch.


Leave a Reply

Your email address will not be published. Required fields are marked *