
Cache everything in Cloudflare also caches logged in users which makes admin bar in WordPress to appear to anonymous users. It is not a good thing and cause negative effect to user experience. We can disable admin bar in WordPress from dashboard settings but there is comment section which also shows logged in as message to not logged in users.
So, is it a good idea to use cache everything in Cloudflare? The answer is yes because I am going to show you how to avoid caching logged in users and how to only purge single page which is modified.
There is a plugin, Cloudflare Page Cache which does the same but it purges all the cache including HTML and static contents like image & CSS. Therefore this article is not only about avoiding logged in user in Cloudflare edge cache but also purging those pages only which are changed.
We are going to use Cloudflare WordPress Plugin along with a Cloudflare Workers script. Cloudflare WordPress Plugin handles cache purging while Cloudflare Workers script enables Edge Cache HTML ensuring no logged in users are being cached and bypass HTML cache for users with cookies. Using this method when a comment is made then only that single page is purged from Cloudflare edge cache and when appearance is changed, everything is purged.
To do so you need to install Cloudflare WordPress Plugin and enable automatic cache management.

For this you need to setup plugin with Global API key first. Which can be found in https://dash.cloudflare.com/profile.

Now you need to run a Cloudflare Workers script that enables HTML edge caching.




Clear all previous code and paste this Workers Script then click save. Gist link – Cloudflare edge-cache-only
// Stop CF edge from caching your site when specific wordpress cookies are present
// script found in https://www.mmaton.com/2018/07/02/cloudflare-cache-anonymous-requests/
addEventListener('fetch', event => {
event.respondWith(noCacheOnCookie(event.request))
})
async function noCacheOnCookie(request) {
// Determine which group this request is in.
const cookie = request.headers.get('Cookie')
// Edge Cache for 1 month
const cacheSeconds = 2592000
if (cookie
&& (
cookie.includes(`wordpress_logged`)
|| cookie.includes(`comment_`)
|| cookie.includes(`wordpress_sec`)
|| cookie.includes(`woocommerce_`)
)) {
const bustedRequest = new Request(request, { cf: { cacheTtl: -1 } })
const response = await fetch(bustedRequest)
const newHeaders = new Headers(response.headers)
newHeaders.append('wp-cache-busted', `true`)
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHeaders
})
} else {
return fetch(new Request(request, { cf: { cacheTtl: cacheSeconds } }))
}
}

You can change const cacheSeconds = 2592000
to adjust the cache time. It is in second and is equivalent to Edge Cache TTL
available in Cloudflare page rules. To deploy workers you have to add a route.



Now your website also became cachy like mine. After doing all the setup, disable your Cache Everything page rule if you have enabled it before. Also you don’t need Edge Cache TTL page rule since it will not work without Cache Everything. The Cloudflare Workers script will take care of both of them.
Cloudflare Workers can do even more. Some examples are changing header on the go and Fast Google Fonts. See How to solve font loading issues due to CORS.
Your super cachy website may also send cache-control
header like cache-control: max-age=3600
, which tells browser to store cache for that time period.

Since we are also caching HTML pages, it will be also stored in browser cache. Due to this page will not load from server when next time user visits that page again instead it will load from users browser cache unless user refreshes the page.
To avoid this you have to set max-age
to low as much as you can. It may depend on how active your site is. I have set it to an hour (3600 seconds). So you don’t get this page updated unless you hit that reload button for an hour. You can set cache-control
header using mod_expires
rule in Apache web server. This can be done by using ExpiresByType text/html "access 1 hour"
inside <IfModule mod_expires.c>
</IfModule>
. This is what my .htaccess
file have in root folder of the site.
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html "access 1 hour"
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType application/javascript "access 1 month"
ExpiresByType application/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresByType image/svg+xml "access 1 year"
ExpiresDefault "access 1 hour"
</IfModule>
You can adjust it like ExpiresByType text/html "access 60 seconds"
.
You also need to set Browser Cache Expiration in Cloudflare to Respect Existing Headers. By doing this Cloudflare will not add its own max-age
header.

For the users who are using WP Super Cache plugin, it sets default expire time is 3 seconds only. You need to check that from browser console. If it is you don’t need to edit .htaccess
like above. But you can always edit to fine tune Browser Cache Expiration. W3 Total Cache plugin users can set Browser Cache Expiration from settings.
You can check if HTML Edge Cache is working or not using browser’s developer tools (Ctrl+Shift+I).
When user is logged in you can see the wp-cache-busted: true
header.

When you browse in private (incognito) mode, you will see cf-cache-status: hit

My site is already boosted with Cloudflare workers let me know how it is working on your site.
Hey,
I also wanted to ask how your given script is different from this below script by cloudflare?
https://raw.githubusercontent.com/cloudflare/worker-examples/master/examples/edge-cache-html/edge-cache-html.js
The script by Cloudflare purges everything when post or comment is updated if KV is not being used. With the script I described in this blog do not purge caches it only caches and bypass is logged in. Purge is done by Cloudflare plugin.
I already described all these stuffs in this blog and you are asking it.
ahan. With that said. Have you tried their 5$ paid worker?
https://workers.cloudflare.com/
Its says in the free version we get low latency after the first request.
but in the unlimited plan its always the lowest.
Will paid worker give some more boost?
The first request will have higher latency in free plan. If your site is large and need better performance you can pay. Paid plan is always better than free.
Hey Sangam,
But when I am checking your article on pingdom it has cf-cache-status:
EXPIRED status.
Here is the report link:
https://tools.pingdom.com/#5b8a54fc17c00000
I am also facing this issue og high TTFB of HTML.
I am using this script: https://github.com/cloudflare/worker-examples/blob/master/examples/edge-cache-html/edge-cache-html.js
When you make a request to website from new location Cloudflare caches files at their Edge Server (near that location). You can see ‘cf-ray
5302f099edd7e634-LHR’ header in your files and html. So for the first time cf-cache-status will be MISS. When the cache is cleared and request is made it will be EXPIRED. If you request again then it will be HIT. You can read more about this here – https://support.cloudflare.com/hc/en-us/articles/200172516.
So a question for you, have you tried testing again? If you did please reply.
Hello Sangam, thank you for the guide. I followed the steps and it’s working great.
However, I got one questions – do we need to disable the `Cache Everying` after adding the edge-cache service worker in CF?
Yes you need disable it when caching is done via Cloudflare Workers. Sorry I missed that to include in the article. I will update the article. Please let me know how it is going. And also please share your website link if you would like to.
Thank you! I figured that out later in the day.