Compression at the CDN Edge

Last reviewed on 2026-10-03

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 compresses responses at the edge with Brotli or gzip and, since 2024, Zstandard, depending on what the visitor advertises. Only content types on Cloudflare's compressible list are compressed: HTML, CSS, JavaScript, JSON, XML, SVG, fonts and application/wasm are on it; the generic application/octet-stream is not. Compression behaviour is controlled with Compression Rules; older guides refer to a separate Brotli toggle under the Speed settings. The edge normalises Accept-Encoding internally before the cache lookup, so cache-key explosion is not a concern.

If your origin already sends a compressed body in an encoding the visitor accepts, the edge can pass it through; there is no double-compression. A Cache-Control: no-transform header from the origin stops Cloudflare from compressing at all. The content-type list, the WebAssembly pitfall and verification commands are covered on the dedicated Cloudflare compression page.

Fastly

Fastly's edge runs VCL services or Fastly Compute. By default the edge does not compress; on VCL services you enable it per response, for example with set beresp.gzip = true; (or set beresp.brotli = true; where Brotli is available) in vcl_fetch for compressible content types, or through the dynamic compression settings in the control panel. Fastly supports gzip and Brotli at the edge; check Fastly's current documentation for Zstandard availability on your service type.

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 the request advertises a supported encoding, the response's Content-Type is on its compressible list (a default list covering common text types), and the object is between 1,000 and 10,000,000 bytes; smaller and larger objects are served as the origin sent them.

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. Cloudflare-specific details are on the Cloudflare compression page, and broken encodings after a CDN change are diagnosed in content decoding errors.

Frequently asked questions

Does Cloudflare compress application/wasm and application/octet-stream?

application/wasm is on Cloudflare's default compressible list; application/octet-stream is not. Serve .wasm files with the correct MIME type so they are compressed.

Is edge compression the same as compression at the origin?

The result for the client is the same — a body with a Content-Encoding header — but the work happens at the CDN instead of your server. Edge compression saves origin CPU; origin precompression allows maximum compression levels for static files.

Should I compress at the origin if my CDN compresses too?

Pick one layer per response type. Precompress static assets at the origin, or send identity and let the edge compress; compressing at both layers wastes CPU and can cause double-compression bugs.

Which file sizes does CloudFront compress?

CloudFront compresses objects between 1,000 and 10,000,000 bytes when the content type is compressible and the viewer supports gzip or Brotli.

Do CDNs support Zstandard?

Support is growing. Cloudflare added Zstandard at the edge in 2024; for other CDNs check the current documentation, as availability differs by product and plan.