Back to all questions

How Does VCL-Based Caching Work Across Multiple CDNs?

Alex Khazanovich
Multi-CDN
October 5, 2026

Honestly, it mostly doesn't, at least not as VCL. Among the major CDNs, only Fastly lets you write VCL, and Fastly's version is its own dialect. So in a multi-CDN setup, your VCL runs on one provider, and every other CDN needs the same caching intent rebuilt in its own rules engine.

‍

What you can carry across is the thinking behind the VCL: what goes into the cache key, how long objects live, when stale content is acceptable and how you purge. Write those decisions down once, translate them for each CDN, then prove every provider behaves the same.

‍

How VCL Controls Caching Behavior at the CDN Edge

‍

VCL, the Varnish Configuration Language, comes from Varnish Cache, the open-source HTTP cache whose community project renamed itself Vinyl Cache in 2025. It reads more like a small programming language than a config file. You write code that runs at fixed points in every request's life.

‍

Fastly subroutineWhen it runsWhat you usually do there
vcl_recvThe request arrivesClean up URLs, strip tracking parameters, decide whether to look in the cache
vcl_hashThe cache key is builtDecide which requests count as the same object
vcl_fetchOrigin response headers arriveSet TTLs and grace periods, or keep the object out of the cache
vcl_deliverThe response heads to the userRemove internal headers, add debug headers

‍

So a few lines of VCL can say "ignore utm parameters, keep product pages for 10 minutes and serve them stale for an hour if the origin goes down." That is edge caching with real control, and it explains why teams that grew up on Fastly lean on VCL so much.

‍

Why VCL Logic Does Not Transfer Between CDN Providers

‍

Your VCL is tied to one vendor, even inside the Varnish world:

‍

  • Fastly's VCL derives from Varnish 2.1.5, and Fastly's own docs say its variant "should be seen as a separate language."
  • Open-source Varnish changed things in version 4.0, where vcl_fetch became vcl_backend_response, so modern Varnish code won't paste into Fastly unchanged.
  • Fastly doesn't allow inline C or VMODs, so extensions you use on self-hosted Varnish simply aren't there.

‍

Outside Fastly, nobody reads VCL at all. Cloudflare uses Cache Rules and Workers. Akamai uses Property Manager behaviors and EdgeWorkers. Amazon CloudFront uses cache policies, CloudFront Functions and Lambda@Edge. Google Cloud CDN and Bunny.net have their own settings too. Every one of them can express most of your logic, but in a different shape.

‍

And no, Fastly isn't retiring VCL. Its docs call VCL fully supported, with Compute offered as an alternative for code-heavy work rather than a replacement you're forced onto.

‍

The Cache Consistency Problems That Appear When VCL Rules Diverge Across CDNs

‍

This is where multi-CDN caching gets sneaky. Leave each provider on its defaults, and the same request gets cached differently depending on which CDN served it.

‍

What differsFastlyCloudflareAmazon CloudFront
Default TTL when the origin sends no cache headers1 hour (2 minutes with custom VCL)2 hours for most 200 responses24 hours
Query strings in the default cache keyIncludedIncludedIgnored by the CachingOptimized policy
Header it trusts firstSurrogate-ControlCloudflare-CDN-Cache-Control, then CDN-Cache-ControlCache-Control, limited by the policy's minimum and maximum TTL

‍

Here's what that looks like for your users:

‍

  • One CDN serves yesterday's price while another serves today's, because their TTLs never matched.
  • Two URLs that differ only by a tracking parameter are one cached object on CloudFront but two on Fastly, so hit ratios and origin load swing whenever traffic shifts.
  • Akamai won't cache responses that carry a Vary header (Accept-Encoding aside), while Fastly and Cloudflare will, so the same origin response caches on some CDNs and misses on others.
  • Stale rules drift too. Fastly and Cloudflare honor stale-while-revalidate, Google Cloud CDN ignores stale-if-error, and Akamai relies on its own serve-stale setting, so an origin outage looks different on every provider.

‍

The one I'd watch closest is private content. CloudFront's CachingOptimized policy has a 1 second minimum TTL, and AWS says a minimum above zero caches content even when the origin sends no-store or private. If your VCL on Fastly passes those responses, your two CDNs now treat private data differently.

‍

How to Maintain Equivalent Caching Behavior When Not Every CDN Supports VCL

‍

You can't copy the code, so copy the decisions:

‍

  1. Write your rules as plain policy first: which paths, which cache key, which TTL, how long stale content is allowed and which tags each object gets.
  2. Move caching intent into origin headers. CDN-Cache-Control (RFC 9213) is honored by Cloudflare and Google Cloud CDN, while Fastly reads Surrogate-Control, so sending both covers most of your stack.
  3. Normalize the cache key the same way everywhere, with one allow list for query strings and headers.
  4. Tag every object for cache invalidation, then purge all providers from one job. Speeds differ: Fastly reports about 150 ms, Cloudflare under 150 ms, CloudFront tag purges under 5 seconds at p95 and Google Cloud CDN about 10 seconds.
  5. Check that each CDN respects your cache headers by requesting the same URLs through every provider and comparing cache status and Age headers.

‍

If I could only keep one step, I'd keep step 5. It's the one teams skip, and it's the one that catches the surprises.

‍

Equivalent doesn't mean identical. Purge speeds and Vary handling will never match exactly across vendors. What you're aiming for is the same outcome for your users: the same object, the same freshness window and a purge that lands everywhere within seconds.

‍

How a Unified Policy Layer Replaces VCL in a Multi-CDN Stack

‍

A unified policy layer flips the model. Instead of writing VCL for Fastly and then copying it by hand into other consoles, you define CDN caching behavior once, covering cache key, TTL, stale TTL and origin header handling. The layer then generates each provider's native config: VCL on Fastly, Cache Rules on Cloudflare, cache policies on CloudFront.

‍

To be fair, it doesn't make VCL disappear on Fastly, and it can only promise what every provider supports. When one CDN lacks a feature, you either settle on a common subset or keep a provider-specific rule and document the gap. A good policy layer still lets you attach code that runs on one CDN only, so your carefully tuned Fastly logic doesn't have to be thrown away.

‍

That trade is usually worth it. It turns your multi-CDN strategy into one policy instead of several hand-maintained configs, and it lets you add or swap a CDN provider without rewriting your caching logic from scratch.