Compression at the CDN Edge

Last reviewed on 2026-04-28

How major CDNs handle gzip and Brotli on the way out, and how to decide whether to compress at edge or origin.

Why CDN compression is a separate topic

A correctly configured origin server compresses every text response and emits Vary: Accept-Encoding. Adding a CDN in front of that origin moves part of the negotiation away from the origin and onto the edge. The edge sees the client's Accept-Encoding first, decides what to fetch from the origin and what to compress itself, and applies its own caching layer keyed by a normalised version of the header.

That displacement creates new questions a single-origin deployment never had to answer: should the edge re-compress what the origin already sent, should the origin send identity to give the edge a free hand, what happens when a Brotli-capable edge sits in front of a gzip-only origin, and how does the edge's cache key interact with Vary? This guide covers the patterns and the per-vendor specifics.

Two delivery models

Almost every production CDN deployment uses one of two compression patterns. The trade-offs differ enough that picking the wrong one quietly costs CPU or bytes.

Pattern A: origin precompresses, edge passes through

The origin holds asset.css, asset.css.gz, and asset.css.br on disk. The edge requests the appropriate variant from the origin (typically by forwarding the client's Accept-Encoding) and caches what comes back. The origin's compression is one-shot and at the maximum level — Brotli 11, Zstandard 19. The edge's job is purely caching and routing.

Best for: static asset bundles produced by a build pipeline. See the precompression guide for the build-side mechanics.

Pattern B: origin sends identity, edge compresses

The origin sends responses uncompressed. The edge applies its own gzip and Brotli pipelines based on the request's Accept-Encoding and stores the result. The origin's CPU is freed up; the edge handles every encoding variant. The edge usually applies a moderate compression level (Brotli 4–5, gzip 6) because it is doing the work on the hot path.

Best for: dynamic HTML, API responses, anything where the origin would otherwise be re-compressing identical bytes per request. The edge cache absorbs most of the volume; the edge compression cost is paid once per cache fill.

Comparing the two patterns

AspectOrigin precompressesEdge compresses
Best compression levelYes — one-shotModerate — per-request
Origin CPUSpent at build timeFree
Edge CPUFree (passthrough)Per cache fill
Suits dynamic contentNoYes
New encoding rolloutBuild-pipeline changeEdge-config change

Most production sites end up with a hybrid: pattern A for hashed static assets, pattern B for HTML and API responses.

Per-vendor behaviour

Cloudflare

Cloudflare Brotli is a single toggle in the dashboard ("Brotli" under Speed → Optimisation). When enabled, the edge compresses text responses with Brotli for clients that advertise br, falling back to gzip otherwise. The edge normalises Accept-Encoding internally before the cache lookup, so cache-key explosion is not a concern. Cloudflare does not currently advertise zstd on responses and strips it from outbound Accept-Encoding when forwarding to the origin in most plans.

If your origin already sends Brotli and Cloudflare's Brotli toggle is enabled, the edge passes the origin's body through unchanged when the encoding matches the request. There is no double-compression. The pattern works for both static and dynamic content as long as the origin advertises a sensible Cache-Control header.

Fastly

Fastly's edge runs VCL or Compute@Edge. By default the edge does not compress; you enable it explicitly with a small VCL snippet that calls set beresp.do_stream = false; set beresp.compress = true; for compressible content types. Fastly supports gzip and Brotli; Zstandard is available on Compute@Edge but not on the legacy VCL pipeline.

The Fastly cache normalises Accept-Encoding automatically when compression is enabled, splitting the cache into gzip / Brotli / identity buckets. Custom normalisation is straightforward in VCL when needed, for example to add a fourth bucket for Zstandard.

Amazon CloudFront

CloudFront supports gzip and Brotli compression at the edge, controlled by a per-distribution "Compress objects automatically" setting and an explicit cache policy that includes Accept-Encoding in the cache key. CloudFront only compresses when both the request advertises a supported encoding and the response's Content-Type is on the compressible list (it ships a default list covering common text types).

One CloudFront-specific behaviour worth knowing: if the origin already sends a Content-Encoding header, CloudFront passes the response through unchanged regardless of the edge compression setting. This makes pattern A reliable but means you cannot rely on the edge to recompress an origin that sends gzip when a client has asked for Brotli — the origin's choice wins.

Akamai

Akamai's behaviour is configurable per property in Property Manager. The "Last Mile Acceleration" feature controls gzip compression at the edge; Brotli at the edge is a separate behaviour available on supporting platforms. Akamai has historically been conservative about normalising Accept-Encoding and will, if asked, key the cache on the literal value — so explicit normalisation in a property rule is recommended for any property serving more than a handful of unique requests per day.

The "edge cache vs browser cache" interaction

Every CDN sits in front of the user's own browser cache. When the edge serves a Brotli body to a browser that requested it, the browser caches that body locally under its own cache key, which (on a correctly behaved browser) also incorporates the Vary headers present on the response. If the user later visits the same page from a different browser profile or after a Brotli-disabling extension changes the request, the browser cache will treat that as a different cache entry and re-fetch.

For the edge cache to behave consistently, the Vary: Accept-Encoding header must be present on the edge's response. Most CDNs add it automatically when their compression feature is on; pattern A deployments where the origin supplies the body need to make sure the origin sets it, since the edge will not add it for a passthrough response. The dedicated Vary guide covers the cache-key-explosion pitfall and the normalisation patterns to avoid it.

A practical decision flow

  1. If your build pipeline already emits hashed, immutable static assets, precompress them at the highest practical Brotli and gzip levels and serve them via your CDN with no edge compression. Origin precompression beats edge compression on those assets every time.
  2. If your HTML is dynamic but cacheable for short windows, enable edge compression and let the edge cache absorb the volume. Configure normalisation explicitly so the cache splits into a small number of buckets, not thousands.
  3. If your responses are uncacheable per-user (authenticated dashboards, personalised feeds), enable origin compression at a moderate level and either disable edge compression or let the edge pass through unchanged. The edge cache cannot help, but the edge can still terminate TLS and forward HTTP/2 efficiently.
  4. Monitor the cache hit rate after any change. A drop after enabling Brotli is a normalisation problem, not a Brotli problem.

Common mistakes

  • Stacking Brotli at edge and origin. The result is that the origin's CPU compresses for nothing and the edge re-compresses for the same client. Pick one layer.
  • Forwarding the literal Accept-Encoding to the origin. Without normalisation at the forward path, the origin receives every variation and produces a unique response for each one, defeating the edge's cache.
  • Forgetting to declare compressible types. A CDN that does not know your content type is text-based will pass the response through uncompressed. Custom MIME types like application/x-yaml or application/wasm often need explicit configuration.
  • Assuming Brotli works on every plan. Several CDNs gate Brotli or Zstandard behind paid tiers or specific platforms. Verify before depending on the encoding being available end-to-end.

Where to go next

For the algorithms themselves, see Brotli, Zstandard, and gzip. For origin-side configuration, the Nginx guide and Apache guide cover the most common open-source origins. For the cache-key mechanics, the Vary guide; for the build-pipeline side, the precompression guide.