Skip to main content

Cache Configuration

Learning Focus

By the end of this lesson you will understand every setting on the Cloudflare Caching → Configuration dashboard page, what each one does, the correct value for most sites, and the operational impact of each option.

Overview: The Configuration Dashboard

The Caching → Configuration page is Cloudflare's global cache control panel. Unlike Cache Rules (which target specific URL patterns), these settings apply zone-wide as defaults — they establish baseline behaviour for your entire domain before any per-URL rules run.

flowchart TD
REQ["Incoming Request"] --> CFG["Zone-Wide Cache Configuration\n(global defaults)"]
CFG --> RULES["Cache Rules\n(per-URL overrides)"]
RULES --> EDGE["Edge Cache\n(serve or miss)"]

style CFG fill:#f6821f,color:#fff,stroke:#e5711e
style RULES fill:#2563eb,color:#fff,stroke:#1e40af
style EDGE fill:#16a34a,color:#fff,stroke:#15803d

Think of it this way: Configuration sets the floor; Cache Rules punch holes in or raise the ceiling for specific paths.

Quick Reference

SettingDefaultFree?Impact
Caching LevelStandardControls query-string caching
Browser Cache TTLRespect OriginHow long browsers cache files locally
Purge CacheN/A (action)Immediately clears cached content from edge
Development ModeOffBypasses edge cache for 3 hours
Always Online™OffServes stale pages when origin is down
Crawler HintsOffNotifies crawlers of content changes
CSAM Scanning ToolOffScans cached images for illegal content
Query String SortOff❌ EnterpriseNormalises query string key order

Caching Level

Caching Level controls how Cloudflare treats query strings (the ?key=value part of a URL) when deciding whether a cached version already exists.

The Three Levels

LevelBehaviourExample
No Query StringOnly cache if URL has no query stringCaches /image.png; ignores /image.png?v=2
Ignore Query StringCache based on path only — ignore query strings entirely/style.css?v=1 and /style.css?v=999 served from the same cache entry
Standard (default)Cache using the full URL including query string/page?lang=en and /page?lang=fr are separate cache entries

Which Level Should You Use?

flowchart TD
Q1{"Do your query strings\nchange the content?"}
Q1 -->|"Yes (e.g., ?lang=en, ?id=42)"| STD["Use Standard\n(default — safe choice)"]
Q1 -->|"No (e.g., ?utm_campaign=email)"| Q2{"Do you want to cache\nbased on path only?"}
Q2 -->|"Yes — marketing/tracking params only"| IGN["Use Ignore Query String\n(highest cache efficiency)"]
Q2 -->|"Unsure"| STD

style STD fill:#16a34a,color:#fff,stroke:#15803d
style IGN fill:#2563eb,color:#fff,stroke:#1e40af

Standard is the right choice for most sites. It is safe: two different query strings always produce two separate cache entries, so you never risk serving the wrong content.

Ignore Query String is powerful for static asset paths where the query string is a cache-busting suffix or a marketing tag — not a content selector. For example:

  • style.css?v=20240301 → cache entry is just /style.css
  • logo.png?utm_source=twitter → cache entry is just /logo.png
caution

Never set Ignore Query String if your site uses query strings to serve different content to different users (e.g., /product?id=42 vs /product?id=99). Both would be served from the same cache entry — showing the wrong product to users.

No Query String is rarely the right choice. It means only the exact URL /file.ext (with no ?...) is ever cached. Any URL with a query string becomes DYNAMIC. Useful only for extremely strict caching of bare asset paths.

Configure via API

Set Caching Level to Ignore Query String
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/cache_level" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value": "ignore_query_string"}'

# Values: "aggressive" (Ignore) | "simplified" (No Query String) | "basic" (Standard)

Browser Cache TTL

Browser Cache TTL controls the max-age directive that Cloudflare sends to the visitor's browser. This instructs the browser how long to cache a file locally before re-requesting it from Cloudflare.

Behaviour Modes

SettingWhat Cloudflare Does
Respect Existing Headers (default)Passes through the Cache-Control headers from your origin untouched
Set a specific TTLOverrides the max-age value sent to browsers, regardless of what your origin says

Available TTL Values

Values range from 30 minutes to 1 year:

30 min → 1 hr → 2 hr → 3 hr → 4 hr → 5 hr → 8 hr → 12 hr → 16 hr → 20 hr → 1 day → 2 day → 3 day → 4 day → 5 day → 6 day → 1 week → 2 week → 1 month → 1 year

When to Override Browser TTL

ScenarioRecommended TTLReasoning
Static assets with hashed filenames1 yearSafe because hash changes when file updates
HTML pagesRespect headers or 1 hourContent changes — short browser cache enables fast updates
API responsesRespect headers or no-store (via origin)User-specific; should not linger in browser
Font files1 week to 1 monthFonts rarely change
Images (non-versioned)1 dayBalance freshness and performance
warning

Browser TTL is not purgeable from the Cloudflare dashboard. Once a browser caches a file for (say) 7 days, you cannot force that specific user's browser to fetch a new version until the TTL expires. This is why short browser TTLs with frequent deploys should use cache-busting filenames (content-hashed assets) rather than relying on short TTLs alone.

Configure via API

Set Browser Cache TTL to 1 day (86400 seconds)
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/browser_cache_ttl" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value": 86400}'

Purge Cache

Purge Cache is an action, not a persistent setting. It immediately invalidates content stored in Cloudflare's edge caches — forcing the next request for each purged URL to fetch a fresh copy from your origin.

Purge Methods

MethodScopeWhen to UseHow
Purge EverythingAll cached content on your zoneMajor redesign, framework update, emergency fixDashboard → Caching → Purge Cache → Purge Everything
Custom Purge (by URL)One or more specific URLsUpdated an image, changed a CSS fileDashboard → Caching → Purge Cache → Custom Purge
Purge by TagAll URLs sharing a Cache-Tag header valuePurge a category of related contentAPI — Enterprise only
Purge by PrefixAll URLs matching a path prefixPurge all content under /blog/API — Enterprise only
Purge by HostnameAll cached content for a specific hostnameMulti-hostname zone cleanupAPI — Enterprise only

Purge by URL via API

Purge specific URLs
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"files": [
"https://example.com/assets/style.css",
"https://example.com/images/hero.jpg"
]
}'
Purge everything
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data '{"purge_everything": true}'

Purge Propagation Time

Purge commands propagate globally across Cloudflare's 330+ PoPs within approximately 30 seconds. During that window, some PoPs may still serve the old cached version. This is generally acceptable — and can be mitigated for critical updates by using cache-busting filenames in your deploy pipeline rather than relying on purge timeliness.

Performance Impact

"Purge Everything" clears your entire edge cache. Every object must be re-fetched from your origin on the next request — this can cause a spike in origin load lasting several minutes while the cache repopulates. Use targeted URL purges whenever possible, especially on high-traffic sites.

Automating Purge in CI/CD

Purge after deployment (GitHub Actions or shell)
#!/bin/bash
# Run this after deploying new static assets

ZONE_ID="your_zone_id"
CF_TOKEN="your_api_token"

# Purge specific updated files
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"files": [
"https://example.com/index.html",
"https://example.com/sitemap.xml"
]
}'

echo "Cache purge complete"

Development Mode

Development Mode temporarily bypasses Cloudflare's edge cache for 3 hours, forcing every request to go directly to your origin server. This lets you see changes in real-time without waiting for cached versions to expire.

How It Works

sequenceDiagram
participant U as Browser
participant CF as Cloudflare Edge
participant O as Origin

Note over CF: Development Mode OFF (normal)
U->>CF: GET /style.css
CF-->>U: 200 OK (cache HIT — fast)

Note over CF: Development Mode ON
U->>CF: GET /style.css
CF->>O: Forward request (bypass cache)
O-->>CF: 200 OK (fresh)
CF-->>U: 200 OK (always fresh)
AspectDetails
Duration3 hours from activation (then auto-disables)
Cache impactBypasses edge cache — does not purge it
Origin loadSignificantly increased — all traffic hits your origin
After expiryCache is not cleared automatically — old cached content returns
Purge After Development Mode

Development Mode bypasses the cache while active, but when it automatically expires after 3 hours, Cloudflare resumes serving whatever was previously cached. If you made changes you want visitors to see permanently, manually purge the cache before or after disabling Development Mode.

Configure via API

Enable Development Mode
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/development_mode" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data '{"value": "on"}'

When to Use Development Mode

Good UsePoor Use
CSS/JS changes during active developmentOn a production site with high traffic
Quick debugging of a visual issueAs a substitute for a proper staging environment
Verifying a fix before purgingLong-running dev sessions (it auto-disables after 3 hrs)

Always Online™

Always Online™ keeps a cached version of your website accessible to visitors even when your origin server is completely unreachable (crash, maintenance, network outage). It does this by serving fallback pages from the Internet Archive's Wayback Machine.

How It Works

flowchart LR
USER["Visitor"] --> CF["Cloudflare Edge"]
CF -->|"Origin reachable"| ORIGIN["Your Server\n(200 OK)"]
CF -->|"Origin unreachable\n(Always Online™ active)"| IA["Wayback Machine\n(Cached Snapshot)"]
IA -->|"Serve archived page"| CF
CF -->|"Degraded but available"| USER

style ORIGIN fill:#16a34a,color:#fff,stroke:#15803d
style IA fill:#f59e0b,color:#fff,stroke:#d97706

Important Limitations

AspectDetails
SourcePages from the Internet Archive — may be days, weeks, or months old
ScopeHTML pages only — not API responses, authenticated sessions, or dynamic content
Dynamic featuresBroken — forms, shopping carts, logins won't work on archived pages
PrivacyEnabling this feature shares your site's content with the Internet Archive
ActivationOnly activates when Cloudflare cannot connect to your origin (521/522/523/524 errors)
Best forInformational / content sites (blogs, docs, marketing sites)
info

Always Online™ is not a replacement for a proper high-availability setup. For business-critical applications, use load balancing, standby servers, or a static fallback page served via Cloudflare Pages instead.

Crawler Hints

Crawler Hints is a protocol that allows Cloudflare to proactively notify search engines and web crawlers (Googlebot, Bingbot, etc.) when your site's content has changed — rather than waiting for the crawler to discover it on its own schedule.

How It Works

When you update content and purge Cloudflare's cache, Crawler Hints generates a change notification that crawlers subscribed to this protocol can act on immediately. The result:

Without Crawler HintsWith Crawler Hints
Crawlers visit on their own schedule (hours or days later)Crawlers notified of change within minutes
Outdated content may persist in search results longerSearch results updated faster after content changes
Crawlers may waste bandwidth rechecking unchanged pagesCrawlers focus effort on actually changed URLs

Considerations

  • Privacy: Cloudflare shares URL change signals with participating crawlers. Review the Supplemental Terms before enabling.
  • SEO benefit: Useful for frequently updated sites (news, e-commerce, documentation) where fast indexing matters.
  • Low risk: Does not affect caching behaviour — it is a notification-only system.

CSAM Scanning Tool

The CSAM (Child Sexual Abuse Material) Scanning Tool is a protective measure that scans hashes of your cached images against a database of known illegal content hashes. It does not scan for adult content generally — it specifically targets known illegal material.

How It Works

StepAction
1Cloudflare computes a hash of each cached image on your zone
2Hash is compared against known CSAM hash databases
3On a match: the URL is immediately blocked (returns 451 Unavailable For Legal Reasons)
4You receive an email alert with the file path so you can remove the original
5Cloudflare reports the match to relevant authorities

Who Should Enable This?

Site TypeRecommendation
User-generated content platforms (forums, social, file hosts)Strongly recommended
E-commerce with user-uploaded product images✅ Recommended
Static informational site (no user uploads)Optional — low risk either way
News / editorial content (professional images only)Optional
warning

This tool only scans content that is cached by Cloudflare. It does not scan files stored on your server that are not being served through Cloudflare. Ensure your origin-level safeguards are also in place.

Query String Sort (Enterprise)

Query String Sort normalises the order of query string parameters before generating a cache key. This means ?a=1&b=2 and ?b=2&a=1 are treated as the same URL and served from the same cache entry.

Why It Matters

Many frontend frameworks, analytics tools, and CDN integrations generate URLs with query parameters in unpredictable orders. Without Query String Sort, these generate separate cache entries for identical content:

/product?color=red&size=M   → Cache entry A
/product?size=M&color=red → Cache entry B ← identical content, wasted cache slot

With Query String Sort: both are normalised to the same sorted key → one cache entry, higher HIT ratio.

FeatureFreeProBizEnterprise
Query String Sort

For non-Enterprise plans, the closest equivalent is setting Caching Level → Ignore Query String for paths where the query string is irrelevant — though that is an all-or-nothing approach per Caching Level setting.

Putting It All Together

Here is the recommended configuration baseline for a typical web application:

SettingRecommended ValueReason
Caching LevelStandardSafe default; preserves query-string specificity
Browser Cache TTLRespect Origin (or 1 day)Let your origin control TTL; override only if origin doesn't set headers
Development ModeOffEnable only during active local debugging sessions
Always Online™On (for content sites)Provides a basic safety net during origin outages
Crawler HintsOnImproves search indexing speed with no downside
CSAM ScanningOn (if user uploads exist)Protective measure with no performance impact

Common Misconceptions

"Development Mode purges my cache when I enable it"

Reality: Development Mode bypasses the cache — it does not purge it. When Development Mode expires after 3 hours, Cloudflare goes back to serving whatever was in the cache before you enabled it. You must manually purge if you want visitors to see your changes after development.

"Browser Cache TTL and Edge Cache TTL are the same setting"

Reality: They control different caches entirely. Edge Cache TTL (set via Cache Rules) controls how long Cloudflare's servers hold the content. Browser Cache TTL (set here) controls how long the visitor's browser holds it locally. Content evicted from the edge cache can still be in the browser cache — and vice versa.

"Purge Everything is safe to run frequently"

Reality: Purge Everything clears 100% of your cached content. Every single subsequent request becomes a cache MISS and hits your origin. On high-traffic sites this can cause a severe origin traffic spike. Prefer targeted URL purges combined with cache-busting filenames in your deployment pipeline.

"Caching Level: Ignore Query String is always better for performance"

Reality: Ignore Query String is only safe when query strings truly don't affect content. If your application serves different pages at /news?page=2 vs /news?page=3, Ignore Query String would serve the same cached page for both — showing page 2 to users requesting page 3.

"Always Online™ serves my latest content during downtime"

Reality: Always Online™ serves a copy from the Internet Archive's Wayback Machine — which may be days, weeks, or even months old. It is a degraded fallback, not a live mirror of your site.

Anti-Patterns to Avoid

Don't Do ThisDo This Instead
Run "Purge Everything" after every deployPurge specific changed URLs; use hashed filenames for assets
Leave Development Mode on overnightIt auto-disables after 3 hrs, but disable manually and purge when done
Set Browser Cache TTL to 1 year on un-versioned HTMLUse short Browser TTL for HTML; use 1-year only for content-hashed assets
Use Ignore Query String on dynamic pagesUse Standard caching level; apply Ignore only via Cache Rule to specific static paths
Enable Always Online™ and think HA is solvedImplement load balancing, health checks, and a proper failover strategy

Key Takeaways

  • The Caching → Configuration page sets zone-wide defaults — Cache Rules can override these for specific paths.
  • Caching Level: Standard is the safe default; use Ignore Query String only when query strings don't affect content.
  • Browser Cache TTL controls how long the visitor's browser caches files — not purgeable from the dashboard.
  • Purge targeted URLs rather than purging everything — it protects your origin from cold-start traffic spikes.
  • Development Mode bypasses cache but does not purge it — always purge manually after a dev session.
  • Always Online™ serves old Wayback Machine snapshots — it is a degraded fallback, not a high-availability solution.
  • Crawler Hints improves search indexing speed — safe to enable on any site that benefits from fast re-indexing.
  • CSAM Scanning is strongly recommended for any site with user-generated image uploads.

What's Next

  • Return to Cache Rules to learn how to override these global defaults for specific URL patterns.
  • Or continue to the next module: DDoS Protection.