Cloudflare's CDN is free and incredibly powerful — but the default settings leave a lot of performance on the table. Most websites running behind Cloudflare are only scratching the surface of what's possible. Static assets get cached automatically, sure, but HTML pages, API responses, and dynamic content fly straight through to your origin server every single time.
In this guide, you'll learn exactly how Cloudflare caching works under the hood, how to configure Cache Rules for maximum performance, and how to measure the real-world impact on your site. By the end, you'll have a setup that reduces origin server load by up to 70% and delivers sub-50ms response times to visitors worldwide.
How Cloudflare Caching Works
Before diving into configuration, it's essential to understand the caching flow. When a visitor requests a resource from your site, here's what happens:
First Request (Cache MISS)
(MISS)
Subsequent Requests (Cache HIT)
(HIT)
Notice that on a cache HIT, your origin server is never contacted. This is the key to both performance and cost savings — every cached response is one less request your server needs to handle.
Every response from Cloudflare includes a
CF-Cache-Status header that tells you exactly what happened:
- HIT — Served from Cloudflare's cache (fastest)
- MISS — Not in cache, fetched from origin and now cached
- EXPIRED — Was cached but TTL expired, re-fetched from origin
- DYNAMIC — Not eligible for caching (default for HTML)
- BYPASS — Cache was intentionally skipped (e.g., by a cache rule)
- REVALIDATED — Cache entry was stale but origin confirmed it's still valid (304)
What Cloudflare Caches by Default
Out of the box, Cloudflare only caches static file extensions. Here's the complete breakdown:
| Status | File Types | Notes |
|---|---|---|
| Cached | .js, .css, .jpg, .jpeg, .png, .gif, .webp, .avif |
Images and frontend assets |
| Cached | .svg, .ico, .woff, .woff2, .ttf, .eot |
Icons and fonts |
| Cached | .pdf, .doc, .mp3, .mp4, .zip, .gz |
Documents and media |
| NOT Cached | .html, .htm, .php |
Dynamic pages — requires explicit rules |
| NOT Cached | JSON, XML, API responses | Dynamic content — requires explicit rules |
Cache Rules: The Modern Way to Control Caching
Cloudflare has deprecated Page Rules in favor of the more powerful Cache Rules system. Cache Rules offer granular control with a familiar expression-based syntax. Let's set up the three essential rules every site needs.
Rule 1: Cache Static Assets Aggressively
Name:
Cache Static Assets
(http.request.uri.path.extension in {"js" "css" "jpg" "jpeg" "png" "gif" "webp" "avif" "svg" "ico" "woff" "woff2" "ttf" "eot" "pdf"})
- Cache eligibility: Eligible for cache
- Edge TTL: 1 month (2,592,000 seconds)
- Browser TTL: 1 week (604,800 seconds)
- Cache Key: Default (includes query string)
Rule 2: Cache HTML Pages (With Smart Bypass)
(http.request.uri.path.extension eq "html" or http.request.uri.path eq "/" or ends_with(http.request.uri.path, "/")) and not http.cookie contains "wordpress_logged_in" and not http.cookie contains "wp-settings"
- Cache eligibility: Eligible for cache
- Edge TTL: 4 hours (14,400 seconds)
- Browser TTL: 10 minutes (600 seconds)
- Respect origin Cache-Control: Off (override with Edge TTL)
Rule 3: Bypass Cache for Admin and API
(starts_with(http.request.uri.path, "/wp-admin") or starts_with(http.request.uri.path, "/wp-login") or starts_with(http.request.uri.path, "/api/") or starts_with(http.request.uri.path, "/admin/") or http.request.uri.path contains "/wp-json/")
- Cache eligibility: Bypass cache
Verifying Your Cache Rules
After setting up your rules, verify they're working by checking the response headers:
cf-cache-status: HIT
age: 86421
$ curl -sI https://example.com/ | grep -i cf-cache
cf-cache-status: HIT
age: 3201
$ curl -sI https://example.com/wp-admin/ | grep -i cf-cache
cf-cache-status: BYPASS
Browser TTL vs Edge TTL: Understanding the Difference
These two TTL values serve very different purposes and getting them right is crucial for a good caching strategy:
| Property | Browser TTL | Edge TTL |
|---|---|---|
| Where it's stored | Visitor's browser cache | Cloudflare's edge servers |
| Who controls it | Cache-Control: max-age header |
Cloudflare Cache Rule setting |
| Can you purge it? | No — user must hard refresh or wait | Yes — instant purge from Cloudflare dashboard |
| Recommended for static assets | 1 week (604,800s) | 1 month (2,592,000s) |
| Recommended for HTML | 5-10 minutes (300-600s) | 2-4 hours (7,200-14,400s) |
Performance Settings: Beyond Caching
Cloudflare offers several performance features beyond basic caching. Here's what to enable and what to watch out for:
Auto Minify
Recommended
Strips whitespace and comments from JS, CSS, and HTML on the fly. Reduces file sizes by 5-15% with zero effort. Safe to enable for all sites — your source files remain untouched.
Brotli Compression
Recommended
Brotli produces ~20% smaller files than gzip for text-based content. All modern browsers support it. Enable it and forget — Cloudflare falls back to gzip for older clients automatically.
Early Hints (103)
Recommended
Sends a 103 Early Hints response before the full HTML, telling the browser to start loading critical CSS and JS. Can shave 100-300ms off perceived load time. No downsides.
HTTP/2 & HTTP/3
Recommended
HTTP/2 enables multiplexing (many files over one connection). HTTP/3 uses QUIC protocol for 0-RTT connections — especially beneficial on mobile and high-latency networks.
Rocket Loader
Use With Caution
Defers all JavaScript execution until after the page renders. Dramatically improves Largest Contentful Paint (LCP) scores, but can break inline scripts, analytics snippets, and some third-party widgets. Test thoroughly before enabling.
Polish (Image Optimization)
Pro Plan Required
Automatically optimizes images with lossy or lossless compression. The WebP conversion alone can reduce image sizes by 25-35%. Worth the Pro plan upgrade for image-heavy sites.
Measuring the Real-World Impact
Numbers don't lie. Here's what typical performance improvements look like before and after proper Cloudflare cache optimization:
Time to First Byte (TTFB)
Before Cloudflare
After Cloudflare (default settings)
After Cloudflare (optimized cache rules)
Origin Server Requests (per day)
Without caching
Default Cloudflare
Optimized cache rules
- Chrome DevTools Network tab — Check
CF-Cache-Statusheader on each request - WebPageTest.org — Run from multiple global locations, see waterfall charts
- Google Lighthouse — Get LCP, FID, and CLS scores before/after optimization
- Cloudflare Analytics — Dashboard shows cache hit ratio, bandwidth saved, and request distribution
Development Mode & Cache Purge
When you're making changes to your site, you need to temporarily bypass caching. Cloudflare offers two approaches:
Development Mode
Temporarily disables all caching for 3 hours. Every request goes directly to your origin server. Perfect for debugging or making rapid design changes.
Toggle: Caching → Configuration → Development Mode
Cache Purge
Instantly invalidates cached content. Two options:
- Purge Everything — Nuclear option, clears entire cache
- Custom Purge — Purge specific URLs, tags, or prefixes
Purging via API
For automated deployments, you can purge cache programmatically:
$ curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
-H "Authorization: Bearer {api_token}" \
-H "Content-Type: application/json" \
--data '{"files":["https://example.com/style.css","https://example.com/"]}'
# Purge everything
$ curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
-H "Authorization: Bearer {api_token}" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
Common Caching Mistakes to Avoid
| Mistake | Consequence | Fix |
|---|---|---|
| Caching HTML without cookie bypass | Logged-in users see cached anonymous pages | Add cookie exclusion in cache rule expression |
| Setting Browser TTL too high for HTML | Content updates take hours/days to appear | Keep Browser TTL under 10 minutes for HTML |
| Not purging cache after deployment | Visitors see old JS/CSS after you update | Purge cache in your CI/CD pipeline, or use versioned filenames |
| Caching POST request responses | Form submissions return cached data | Only cache GET requests (Cloudflare default) |
| Leaving Development Mode on | All caching disabled for 3 hours | Use Custom Purge instead for quick updates |
Panelica Integration: One-Click Cache Management
If you're running Panelica as your server panel, you get built-in Cloudflare integration that eliminates the need to switch between dashboards:
- One-click cache purge — Purge all or specific URLs directly from your domain's Cloudflare tab
- Development Mode toggle — Enable/disable without logging into Cloudflare
- Under Attack Mode — Instant activation when you detect suspicious traffic
- DNS record management — Add, edit, and delete DNS records from the panel
- WordPress Redis cache — Object cache + full-page caching at the server level
When you combine Panelica's server-level Redis cache with Cloudflare's edge cache, you get a multi-layer caching architecture that's incredibly fast:
Response Time: Panelica + Cloudflare vs Bare Metal
Bare metal (no caching)
Panelica Redis cache only
Panelica Redis + Cloudflare optimized
Summary: Your Cache Optimization Checklist
- Create Cache Rule for static assets (1 month Edge TTL, 1 week Browser TTL)
- Create Cache Rule for HTML with logged-in user bypass (4 hour Edge, 10 min Browser)
- Create Bypass Rule for admin, API, and login pages
- Enable Auto Minify (JS, CSS, HTML)
- Enable Brotli Compression
- Enable Early Hints (103)
- Enable HTTP/2 and HTTP/3
- Test Rocket Loader on a staging domain first
- Verify cache status with
curl -sIand checkCF-Cache-Status - Add cache purge to your deployment pipeline
- Monitor cache hit ratio in Cloudflare Analytics (aim for 85%+)
Proper Cloudflare cache configuration is one of the highest-impact, lowest-effort optimizations you can make. Spend 15 minutes setting up these three cache rules, and your site will be faster, your server load will drop dramatically, and your visitors will have a better experience — all at zero additional cost.