---
title: "Cloudflare cache warming: why one server can't preload 300+ colos — warmup.rocks"
description: "Cloudflare caches per data center. How to actually preload the Cloudflare cache — classic CDN cache, Workers Cache and Tiered Cache — from every region."
canonical: https://warmup.rocks/blog/cloudflare-cache-warming
---

Cloudflare

# Cloudflare cache warming: why one server can't preload 300+ colos

July 2026 · 9 min read · [← All posts](https://warmup.rocks/blog/)

Search for "preload Cloudflare cache" and you'll find the same recipe over and over: run a crawler over your sitemap, done. It feels right — and it barely works. To understand why, you need one fact about Cloudflare's architecture, and once you have it, everything about warming strategy falls into place.

## The one fact: caches are per-colo

Cloudflare operates 300+ data centers ("colos"). When a visitor requests your page, anycast routing sends them to the nearest colo — and **that colo's cache** answers. There is no global Cloudflare cache. A page cached at FRA (Frankfurt) is entirely cold at NRT (Tokyo), GRU (São Paulo) and SYD (Sydney).

You can see this yourself: request the same URL through a VPN from two continents and compare the `cf-ray` header (the colo code is after the dash) and `cf-cache-status`. Frankfurt says HIT; Tokyo says MISS — for a URL you "warmed" minutes ago.

## Why the single-server crawler fails

A crawler on your server (or a WordPress preload plugin, or a GitHub Action) sends all its requests from one place. Anycast routes them all to the _same_ colo. Result: you've warmed exactly one edge location out of 300+ — usually the one closest to your origin, which is precisely where warming matters least, because your origin round trip is shortest there anyway.

Server-side preloading is still worthwhile for what's on your server: page caches, object caches, OPcache. Just don't expect it to move your Cloudflare hit ratio for visitors on other continents.

## What about the Cache Reserve / paid options?

Cloudflare offers pieces of this puzzle natively. **Tiered Cache** (free) routes cache misses through larger upper-tier colos, so a miss in a small location can be answered by a regional hub instead of your origin. **Cache Reserve** (paid, R2-backed) keeps a persistent copy of cacheable assets so evictions hurt less. Both are worth enabling — and neither eliminates the cold-start: the first request per region is still slow, entries still expire, and the Workers Cache (below) is not covered by Cache Reserve at all.

## The Workers Cache wrinkle

If your site renders in a Cloudflare Worker — Astro, Next.js on Workers, or a CMS like EmDash — your HTML is typically cached in the **Workers Cache**, which sits in front of the Worker. It's also per-colo, and it has an extra property: zone-level purge ("Purge Everything") doesn't touch it, and Cache Rules don't apply to it. It's controlled by response headers (`Cloudflare-CDN-Cache-Control`, `Cache-Tag`) and the Workers Cache purge API. For warming purposes the rule is the same: only a request that lands in a given colo warms that colo's Workers Cache.

## Warming Cloudflare properly

The requirements follow directly from the architecture:

1.  **Geographic distribution.** Requests must enter Cloudflare's network in many regions. In practice that means egress through proxies or agents in dozens of countries — each request then warms the colo that anycast assigns to that region.
2.  **Browser-shaped requests.** Send `Accept-Encoding: gzip, br` and download the full body. Cloudflare caches compressed variants, and interrupted downloads may not be cached.
3.  **Bot-protection allowance.** Super Bot Fight Mode will challenge datacenter-IP traffic. A WAF skip rule keyed on a secret header solves this cleanly (never allow-list by IP — pools change).
4.  **Verification via `cf-cache-status`.** MISS on the first pass, HIT on the second. If the second pass still says MISS, your responses aren't cacheable — check `Cache-Control` and cookies before blaming the warmer.
5.  **Rhythm matched to TTLs.** Warm at roughly half your edge TTL, and re-warm right after every deploy or purge.

## What coverage looks like in practice

You don't need a proxy in all 300+ cities — anycast concentrates traffic. From our own measurements: requests through proxies in 42 countries reach about **39 distinct Cloudflare colos** directly per pass. Tiered Cache then extends the effect: the upper-tier hubs that serve the remaining locations are warmed as a side effect, so even colos never hit directly stop travelling to the origin.

## Checklist

-   Enable Tiered Cache (free, one toggle).
-   Make your HTML cacheable at the edge (Cache Rule or `Cloudflare-CDN-Cache-Control`) with purge-on-publish for freshness.
-   Warm from many regions, on a schedule, plus after deploys.
-   Watch `cf-cache-status` per colo, not just globally.
