CloudFront

CloudFront cache warming: 600+ POPs, regional edge caches, and how to fill them

July 2026 · 8 min read · ← All posts

CloudFront is the largest CDN by location count: 600+ edge POPs feeding from 13 regional edge caches (RECs). That two-tier design is great news for warming, because every warming request does double duty. It's also the CDN where HTML caching is most often accidentally disabled, so let's start there.

First: is your HTML cacheable at all?

CloudFront honors your origin's Cache-Control. The most common finding when we point the cache checker at a CloudFront site: x-cache: Miss from cloudfront on every request, forever, because the origin sends no-cache, private, or nothing at all while the distribution uses the CachingDisabled policy for dynamic behavior. Fix the policy first (use CachingOptimized or a custom cache policy with a real TTL for anonymous HTML), or warming has nothing to warm. The headers to read: x-cache (Hit from cloudfront / Miss from cloudfront) and x-amz-cf-pop (which POP answered, e.g. FRA56-P5).

The two-tier cache: why warming CloudFront pays twice

When an edge POP misses, it doesn't go straight to your origin. It asks its regional edge cache first. RECs are bigger, fewer (13 worldwide) and hold objects longer than edge POPs. For warming this is a gift:

So even a modest multi-region warming pass (one request per continent-region) upgrades the "worst case" for your whole audience from origin-latency to REC-latency. A denser pass (one request per country) then fills the actual edge POPs your visitors touch. That's the model warmup.rocks uses: requests from 40+ countries land at the POPs real traffic lands at, and the RECs come along for free.

Invalidations: the cold-cache generator

Every deploy that runs aws cloudfront create-invalidation --paths "/*" empties all 600+ POPs and all 13 RECs at once. Two things to know (details in AWS's invalidation docs):

Origin Shield: one more layer, same story

CloudFront's Origin Shield (an extra REC acting as the single funnel to your origin) further concentrates origin fetches. With shield enabled, a global warming pass typically costs your origin a single-digit number of requests per URL. If your origin is a slow CMS or a Lambda@Edge/SSR function, that's the difference between a warming pass being free and being a load test.

Practical CloudFront warming setup

  1. Cache policy: real TTLs for anonymous HTML; exclude cookies/headers you don't vary on (every extra cache key dimension multiplies the objects to warm).
  2. Versioned assets + targeted invalidations instead of /* where possible.
  3. Origin Shield on if your origin is slow or expensive.
  4. Scheduled multi-location warming matched to your TTLs, plus a deploy-hook triggered run after each invalidation.
  5. Verify per location: the global TTFB test shows the REC effect directly: warm regions answer in <100 ms, cold ones show your full origin round trip.

Invalidate on deploy, warm before the first visitor

warmup.rocks warms your CloudFront distribution from 90+ locations on a schedule and on every deploy via hook. CloudFront is auto-detected (x-cache / x-amz-cf-pop), hit ratio reported per location.

Start your 7-day free trial