
CDN Caching Strategy with Cloudflare
- AuthorLiam K.
- Date
- Time14 minutes
Caching Model
Split content into immutable static assets, short-lived HTML, and no-cache private/API responses.
Step 1: Set Origin Cache Headers
http
# Static assets (hashed filenames)
Cache-Control: public, max-age=31536000, immutable
# HTML pages
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=120
# API/private content
Cache-Control: no-storeStep 2: Nginx Header Example
nginx
location ~* \\.(css|js|png|jpg|jpeg|gif|svg|webp|woff2)$ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
location / {
add_header Cache-Control "public, max-age=60, s-maxage=300, stale-while-revalidate=120";
}
location /api/ {
add_header Cache-Control "no-store";
}Step 3: Cloudflare Recommended Settings
- Caching: Standard
- Browser Cache TTL: Respect Existing Headers
- Always Use HTTPS: On
- Auto Minify: JS/CSS/HTML as needed
Step 4: Cache Rules
text
Rule 1: If URI path matches /assets/*
Action: Cache eligibility = Eligible
Edge TTL: 1 month
Browser TTL: Respect origin
Rule 2: If URI path matches /api/*
Action: Cache eligibility = Bypass cacheStep 5: Purge Strategy
Prefer versioned asset filenames and only purge HTML on release.
bash
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"files":["https://example.com/","https://example.com/pricing"]}'Step 6: Validate Cache Behavior
bash
curl -I https://example.com/
curl -I https://example.com/assets/app.abc123.jsLook for headers such as cf-cache-status: HIT, cache-control, and correct content variation behavior.
Step 7: Avoid Common Mistakes
- Never cache authenticated API responses unless explicitly segmented by key.
- Avoid long TTL on unversioned assets.
- Do not purge entire zone on every deploy.
"Good caching strategy is a release strategy. The CDN amplifies whatever discipline your deploy process has."



