How to Cache Your Ghost Blog with Cloudflare (Updated for 2026)

Caching your Ghost blog with Cloudflare can reduce Time to First Byte (TTFB) by up to 81% and cut origin server requests by 95%, according to Cloudflare's own benchmarks. This guide covers Ghost's built-in cache settings, Cloudflare's new Cache Rules (replacing the deprecated Page Rules), and automated cache purging with Workers.

Why should you cache your Ghost blog with Cloudflare?

Ghost is a Node.js application that generates HTML dynamically on each request. Without caching, every visitor triggers a fresh database query and template render on your origin server. For a blog that only changes when you publish or edit content, this is wasteful.

Cloudflare operates over 330 data centers worldwide. When you cache your Ghost blog at the edge, visitors receive content from the nearest Cloudflare server instead of your origin. According to Cloudflare community benchmarks, properly configured edge caching delivers:

  • TTFB reduction of 66-81% — typical drops from 500ms+ down to under 100ms
  • Cache hit rates of 80-90% — up from the default 30% without optimization
  • Origin server load reduced by 60-90% — fewer requests hitting your Ghost instance
  • LCP improvements of up to 50% — Largest Contentful Paint dropping from 3.8s to 1.9s in documented cases

For self-hosted Ghost blogs on modest hardware (DigitalOcean droplets, Hetzner VPS), this can mean the difference between a site that struggles under traffic spikes and one that handles them effortlessly.

How do you enable caching in Ghost's config file?

Ghost's built-in caching controls HTTP cache headers sent to browsers and CDNs. You configure this in your config.production.json file, typically located at /var/www/ghost/config.production.json for standard installations.

Add the caching section to your config file:

{
  "url": "https://yourblog.com",
  "database": {
    "client": "mysql"
  },
  "caching": {
    "contentAPI": {
      "maxAge": 60
    },
    "frontend": {
      "maxAge": 600
    }
  }
}

Here's what each setting controls:

Setting What It Caches Recommended Value Effect
contentAPI.maxAge Ghost Content API responses (JSON) 60 seconds Sets Cache-Control: public, max-age=60 on API responses
frontend.maxAge HTML pages rendered by Ghost 600 seconds (10 min) Sets Cache-Control: public, max-age=600 on page responses

After saving the file, restart Ghost for changes to take effect:

ghost restart

Important: These settings only add Cache-Control headers to Ghost's responses. They tell Cloudflare (and browsers) how long to cache content, but Cloudflare still needs to be configured to respect these headers — which brings us to the next step.

Should you use Redis for Ghost's internal cache?

By default, Ghost stores its internal cache in memory. For high-traffic sites, Ghost's official documentation recommends using the built-in Redis cache adapter. Redis persists cache across Ghost restarts and doesn't compete with your Node.js process for RAM.

This is separate from Cloudflare caching — Ghost's internal cache handles things like image size calculations and frequently accessed data, while Cloudflare caches the full HTTP response at the edge.

What is the difference between edge cache and browser cache?

Understanding this distinction is critical for configuring your caching strategy correctly.

Cache Type Where It Lives Who It Helps TTL Control
Browser Cache On each visitor's device Returning visitors only Cache-Control: max-age header
Edge Cache Cloudflare's 330+ global data centers All visitors in that region Edge Cache TTL setting in Cache Rules

Edge caching is the bigger win. When a visitor in Tokyo requests your blog, Cloudflare serves the cached version from its Tokyo data center instead of routing the request to your origin server in, say, New York. The first visitor to that edge location triggers a cache fill, and every subsequent visitor in that region gets the cached version instantly.

Browser caching only helps when the same person revisits your site. Edge caching helps every visitor in an entire geographic region.

How do you set up Cloudflare Cache Rules for Ghost? (Replaces Page Rules)

Important 2025 update: Cloudflare deprecated Page Rules and replaced them with dedicated Cache Rules. If you're following older tutorials that reference Page Rules, switch to Cache Rules instead — they offer more granular control and higher limits.

Here's how to configure Cache Rules for your Ghost blog:

Step 1: Create a cache rule for public content

  1. Log in to your Cloudflare dashboard
  2. Select your domain
  3. Navigate to Caching → Cache Rules
  4. Click Create rule
  5. Name it: "Cache Ghost public pages"
  6. Set the expression: (not starts_with(http.request.uri.path, "/ghost/")) and (not starts_with(http.request.uri.path, "/p/"))
  7. Under Cache eligibility, select Eligible for cache
  8. Set Edge TTL to 2 hours (7200 seconds)
  9. Click Deploy

This rule caches all public pages while excluding the Ghost admin panel (/ghost/) and preview links (/p/).

Step 2: Create a bypass rule for the admin panel

  1. Create another Cache Rule
  2. Name it: "Bypass cache for Ghost admin"
  3. Set the expression: (starts_with(http.request.uri.path, "/ghost/"))
  4. Under Cache eligibility, select Bypass cache
  5. Click Deploy

This ensures your admin dashboard, editor, and authentication always hit the origin server directly.

Why Cache Rules instead of Page Rules?

According to Cloudflare's migration guide, Cache Rules provide several advantages over the legacy Page Rules system:

  • Higher rule limits — Free plans get 10 Cache Rules vs. 3 Page Rules
  • More granular matching — Use field-based expressions instead of simple URL patterns
  • Stackable rules — Multiple Cache Rules can apply to the same request (Page Rules used first-match-wins)
  • Better performance — Evaluated more efficiently at the edge

How do you automate cache purging when content changes?

The biggest challenge with aggressive caching is stale content. When you publish or update a post, Cloudflare continues serving the old cached version until the TTL expires.

The solution: use a Cloudflare Worker that automatically purges cache when Ghost publishes or updates content. Here's how it works:

  1. Create a custom integration in Ghost Admin under Settings → Integrations
  2. Add a webhook that fires on post.published and post.updated events
  3. Point the webhook at a Cloudflare Worker URL
  4. The Worker calls Cloudflare's Cache Purge API to invalidate the changed page

To set up the Worker, you'll need a Cloudflare API token with Zone.Cache Purge permission. This approach gives you the best of both worlds: aggressive caching with 2-hour TTLs for performance, plus instant updates when you publish new content.

How do you verify that caching is working?

Method 1: Using curl in the terminal

Run this command to check cache headers:

curl -svo /dev/null https://yourblog.com/ 2>&1 | grep -i "cf-cache-status\|age:\|cache-control"

Look for these headers in the response:

Header Value Meaning
cf-cache-status HIT Served from Cloudflare's edge cache
cf-cache-status MISS Fetched from origin, now cached at edge
cf-cache-status DYNAMIC Not cached — check your Cache Rules
age 3600 Content has been cached for 3600 seconds
cache-control public, max-age=600 Ghost's caching headers are working

Tip: The first request will always be a MISS. Run the command twice — the second request should return HIT with an age value above 0.

Method 2: Using browser DevTools

  1. Open Chrome and navigate to your blog
  2. Press Ctrl + Shift + I (or Cmd + Option + I on Mac) to open DevTools
  3. Go to the Network tab
  4. Refresh the page with Ctrl + Shift + R (hard refresh)
  5. Click the main document request (your blog URL)
  6. Check the Response Headers for cf-cache-status, cache-control, and age

Method 3: Cloudflare Analytics dashboard

For ongoing monitoring, check Caching → Overview in your Cloudflare dashboard. This shows your cache hit ratio, bandwidth saved, and requests served from edge vs. origin. A well-configured Ghost blog should maintain a cache hit rate above 80%.

What common issues should you troubleshoot?

Even with correct configuration, several issues can prevent caching from working as expected:

Problem Cause Solution
cf-cache-status: DYNAMIC on all pages Cache Rule not matching or not deployed Verify your rule expression and ensure it's active
Ghost admin panel not loading Admin paths being cached Add explicit bypass rule for /ghost/* paths
Preview links showing published version Preview paths (/p/) being cached Exclude /p/ from caching rules
Stale content after publishing No cache purge mechanism Set up Cloudflare Worker with Ghost webhooks
Low cache hit rate (<50%) Short TTLs or too many query string variations Increase Edge TTL and enable query string sorting
Members/login not working Cookies being stripped by cache Bypass cache for authenticated paths or use Workers for cookie-aware caching

Based on my experience running Ghost blogs behind Cloudflare, here's the configuration I recommend for most sites:

Layer Setting Value Reason
Ghost config frontend.maxAge 600 (10 min) Browser cache for returning visitors
Ghost config contentAPI.maxAge 60 (1 min) API consumers get near-fresh data
Cloudflare Cache Rule Edge Cache TTL 7200 (2 hours) Edge serves cached pages for 2 hours
Cloudflare Cache Rule Bypass for /ghost/* Bypass Admin panel always hits origin
Cloudflare Worker Cache purge on publish Automatic Fresh content served immediately after publishing

This setup delivers sub-100ms TTFB for most visitors while ensuring content updates appear within seconds of publishing.

Frequently asked questions

Does caching affect Ghost's member features or subscriptions?

Yes, it can. Ghost's member authentication relies on cookies. If you cache pages aggressively, logged-in members may see cached versions without their membership context. For sites using Ghost's membership features, bypass cache for authenticated requests or use a Cloudflare Worker that detects the ghost-members-ssr cookie and serves uncached responses to logged-in users.

How much does Cloudflare caching cost for a Ghost blog?

Cloudflare's Free plan includes caching, Cache Rules (10 rules), and their global CDN. For most Ghost blogs, this is sufficient. If you need Cloudflare Workers for automated cache purging, the Workers Free plan includes 100,000 requests per day. Paid plans start at $5/month for Cloudflare Workers Paid with 10 million requests per month.

Should I use Cloudflare APO for my Ghost blog?

No. Cloudflare's Automatic Platform Optimization (APO) is currently designed for WordPress only and requires the Cloudflare WordPress plugin. For Ghost blogs, use the Cache Rules approach described in this guide — it achieves similar results.

What Edge Cache TTL should I use?

For most Ghost blogs, 2 hours (7200 seconds) is a good balance between performance and freshness. If you have automated cache purging via Workers and webhooks, you can increase this to 24 hours for even better cache hit rates. Blogs that publish multiple times per day may want shorter TTLs of 30-60 minutes.

How do I clear the Cloudflare cache manually?

In the Cloudflare dashboard, go to Caching → Configuration and use Purge Everything for a full cache clear, or Custom Purge to clear specific URLs. Note that this only purges Cloudflare's edge cache — it won't affect content already cached in visitors' browsers.

Will caching break my Ghost blog's RSS feed or sitemap?

Ghost generates RSS feeds at /rss/ and sitemaps at /sitemap.xml. These will be cached along with other content. For RSS feeds, this is usually fine since feed readers check periodically. If you need sitemaps to update immediately (for search engine crawls after publishing), include them in your cache purge Worker logic.

Can I cache my Ghost blog if I'm using Ghost(Pro) hosting?

Ghost(Pro) includes built-in caching and a CDN through its hosting infrastructure. Adding Cloudflare in front of Ghost(Pro) can still provide benefits like DDoS protection, Web Application Firewall (WAF), and additional edge caching, but the performance gains will be smaller since Ghost(Pro) already handles caching.

What's the difference between "Cache Everything" in Page Rules and "Eligible for cache" in Cache Rules?

According to Cloudflare's migration guide, "Eligible for cache" in Cache Rules is the equivalent of "Cache Everything" in Page Rules. The key behavioral difference: Page Rules used first-match-wins logic, while Cache Rules are stackable — multiple matching rules combine and apply to the same request, with the last matching rule taking priority.

Subscribe to Ghost SEO

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe