Learn
What Is a Codec? Video and Audio Codecs Explained
A codec (short for coder-decoder) is an algorithm, plus the software or hardware that implements it, that compresses ...
Here is the failure pattern we see most often. A route sets revalidate to 60 seconds on Vercel. A well-meaning Cloudflare Edge TTL of 4 hours sits in front of it. Users can now see HTML up to 4 hours and 1 minute old, and calling revalidatePath does nothing about it, because on-demand revalidation only purges Vercel's cache. That is the core problem with a Next.js Cloudflare CDN layer: you run two caches with two TTLs, and the invalidation signal reaches only one of them.
This 2026 update covers the full setup: DNS and proxy mode, cache rules for static, ISR and dynamic routes, and the header conflicts between the two edges. It also includes a staleness-budget model, a decision table for when to skip Cloudflare entirely, and a debugging procedure that tells you which edge served a response.

Every proxied request passes through two tiers. The Cloudflare edge is the tier users see. The Vercel edge network, branded Vercel CDN since 2025, sits behind it as the second tier, and Vercel Functions handle rendering. Cloudflare treats Vercel as an origin. Vercel sees Cloudflare egress IPs as clients.
Three things changed for returning readers as of 2026:
| Route | Cloudflare Cache Rule | Why |
|---|---|---|
| /_next/static/ | Eligible, Edge TTL 1 year, respect origin | Content-hashed and immutable |
| /_next/image | Eligible, keep full query string in cache key | Width and quality live in the query; ignoring it serves wrong sizes |
| ISR and cached HTML | Eligible, Edge TTL "use cache-control header if present" | Let targeted headers decide; never override |
| /api/, Server Actions, draft mode | Bypass | POST mutations and preview cookies |
| Authenticated SSR | Bypass when a session cookie is present | Prevents cross-user data leaks |
This is the part most Next.js CDN caching guides get wrong. When Vercel sees plain Cache-Control with s-maxage, it consumes that header, then strips s-maxage and stale-while-revalidate before forwarding the response. Cloudflare therefore receives an ISR page marked public, max-age=0, must-revalidate. The result is DYNAMIC or a zero-TTL cache on Cloudflare, which is safe but pointless. Teams then add an Edge TTL override, and that override is what creates the stale-content incident described at the top.
| Header set by the app | Vercel CDN | Cloudflare |
|---|---|---|
| Cache-Control with s-maxage | Honors, then strips | Sees max-age=0 |
| Vercel-CDN-Cache-Control | Honors, consumes | Never sees it |
| CDN-Cache-Control | Honors, forwards | Honors |
| Cloudflare-CDN-Cache-Control | Passes through | Honors, highest priority |
The working pattern is to set Vercel-CDN-Cache-Control to your real revalidate window and Cloudflare-CDN-Cache-Control to a short TTL, typically 30 to 120 seconds. Cloudflare then absorbs request bursts while Vercel remains the source of truth for freshness.
Worst-case staleness is roughly the Cloudflare TTL plus the Vercel revalidate window plus one render time. Write that number down for every route class. If the business can't tolerate it, you have two options. You can shorten the Cloudflare TTL, or you can wire revalidateTag calls to a Cloudflare purge-by-URL or purge-by-tag API call in the same handler. Deploys need the same hook, because Vercel purges its own cache on deploy and Cloudflare does not.
App Router serves HTML and React Server Component flight data from the same path, differentiated by the RSC and Next-Router-State-Tree request headers plus the _rsc query parameter. Cloudflare ignores Vary for non-image content. If a cache rule strips query strings from the cache key, a browser can receive raw flight data instead of a page. Keep the query string in the key for HTML routes.
| Situation | Recommendation |
|---|---|
| Mostly dynamic or personalized SSR | Vercel alone; a second hop adds latency with nothing to cache |
| Org already standardized on Cloudflare DNS, WAF and Zero Trust | Cloudflare in front with the targeted-header pattern |
| High Vercel data transfer bills from cacheable pages | Cloudflare in front, short HTML TTLs, long static TTLs |
| Heavy media or downloads | Split hostname: app on Vercel, assets on a volume-priced CDN |
| Heavy use of Vercel Firewall, BotID or geo middleware | Vercel alone, or accept degraded client signals |
The cost row deserves numbers. Per Vercel's 2025 published pricing, Pro includes 1 TB of Fast Data Transfer, and overage starts at $0.15 per GB in the cheapest regions. Check current regional rates, as 2026 figures may differ. At that rate, 100 TB a month of media overage runs about $15,000. Cloudflare's self-serve plans don't meter cached bandwidth, but their terms steer large video and file distribution toward paid products.
For the split-hostname pattern, the realistic comparison set is the volume-priced CDNs: Bunny.net, CDN77, Gcore and BlazingCDN. Bunny's storage and image tooling is mature, and it deserves a trial. BlazingCDN offers Anycast routing with built-in failover and flexible configuration. On BlazingCDN's volume pricing, that same 100 TB costs $415 a month, and rates fall to $2.50 per TB ($0.0025 per GB) at volume (as of October 2026). That spread matters for enterprise media workloads.
Send HEAD requests from your terminal's HTTP client and read four headers:
To isolate Vercel, pin DNS resolution for the hostname to 76.76.21.21 in your client, or query the deployment's vercel.app URL. Compare the two responses. If Vercel returns fresh content and Cloudflare returns stale, purge Cloudflare and remove any Edge TTL override. A 403 that only appears when the request is proxied usually points to Vercel Deployment Protection or firewall rules challenging Cloudflare IPs.
Our 2026 operating targets are above 85% cache hit ratio on static routes, 50 to 70% on ISR HTML, and p95 TTFB under 200 ms on cached pages. Watch ISR revalidation invocations as well. A flatline means Cloudflare is absorbing everything. For emergency rollback, switch the record to DNS-only. Traffic goes straight to Vercel as soon as resolvers pick up the change.
It works, but Vercel discourages it. The proxy hides real client IPs from Vercel's firewall, bot detection and rate limiting. If you proceed, use Full (Strict) TLS, read cf-connecting-ip in middleware, and avoid rules that challenge traffic Vercel sends back.
Vercel strips s-maxage from Cache-Control before forwarding the response, so Cloudflare sees max-age=0. Emit CDN-Cache-Control or Cloudflare-CDN-Cache-Control from the route and make the path eligible for cache.
Call Cloudflare's purge API from the same handler that runs revalidatePath or revalidateTag. Add the same purge to your deploy pipeline. Otherwise Cloudflare serves its copy until its own TTL expires.
For most Next.js apps, yes. It caches ISR and static output globally and understands framework semantics natively. Adding Cloudflare pays off mainly through consolidated security tooling or bandwidth cost savings, not raw latency.
Yes, if the query string is dropped from the cache key. HTML and RSC flight data share a path. Keeping the _rsc parameter in the key prevents Cloudflare from serving flight data as a page.
Pick your three highest-traffic ISR routes. For each one, record cf-cache-status, age and x-vercel-cache from two regions, trigger an on-demand revalidation, and repeat the requests. If age does not reset within your staleness budget, you have found the gap between your two caches. Then decide whether to shorten the Cloudflare TTL, wire in purges, or take Cloudflare off the HTML path entirely. We'd like to hear which one you chose, and what your purge latency looked like.
Heavy traffic.
Light bill.
The CDN for video and large traffic
Learn
A codec (short for coder-decoder) is an algorithm, plus the software or hardware that implements it, that compresses ...
Learn
The Apple CDN is a layered stack rather than one network. It combines Apple's own edge caches, many embedded inside ISP ...
Learn
Video compression is the process of encoding moving images into far fewer bits by removing spatial redundancy inside ...