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: it means a warming strategy gets leverage. 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