Skip to main content
CDN

Compression

How Easel compresses eligible responses with Brotli and gzip.

Easel automatically compresses eligible responses before sending them to visitors.

When supported by the client, Easel prefers Brotli compression and falls back to gzip. Responses that are already compressed or unlikely to benefit from compression are sent unchanged.

Supported encodings

Easel negotiates compression using the request’s Accept-Encoding header.

For example:

Accept-Encoding: br, gzip

When both encodings are supported, Easel prefers Brotli:

Content-Encoding: br

When Brotli is unavailable but gzip is supported, Easel may return:

Content-Encoding: gzip

When the client does not advertise a supported encoding, Easel sends the response without compression.

Automatic compression

Compression can apply to both static files and dynamic responses.

Common examples include:

  • HTML
  • CSS
  • JavaScript
  • JSON
  • XML
  • SVG
  • plain text
  • source maps
  • WebAssembly
  • common font and manifest formats

Easel compresses a response only when doing so is expected to reduce its transferred size.

Responses that are not compressed

Easel generally does not compress:

  • responses that already include Content-Encoding
  • byte-range responses
  • very small responses
  • formats that are already compressed
  • responses with an unsupported or missing content type

Common already-compressed formats include:

  • JPEG
  • PNG
  • WebP
  • AVIF
  • GIF
  • MP4
  • WebM
  • MP3
  • ZIP
  • gzip archives
  • Brotli-compressed files

Compressing these formats again usually provides little benefit and can increase processing overhead.

Minimum response size

Easel does not compress responses smaller than 256 bytes.

For very small responses, compression headers and processing can outweigh the reduction in payload size.

This threshold applies to the uncompressed response body.

Precompressed responses

When an application or origin already returns a compressed response, Easel preserves the encoding instead of compressing it again.

For example:

Content-Encoding: gzip

The response body must match the declared encoding.

Do not manually set Content-Encoding unless the body has already been encoded. Declaring gzip or Brotli for an uncompressed body causes browsers and other clients to fail when decoding the response.

Content negotiation

Compressed and uncompressed responses are different representations of the same resource.

Easel adds or preserves:

Vary: Accept-Encoding

This prevents a cache from serving a Brotli-compressed response to a client that does not support Brotli.

Applications should not remove Accept-Encoding from Vary when a response can be compressed.

Compression and caching

Compression works alongside CDN caching.

A cacheable response can be stored and later delivered using an encoding supported by the requesting client.

For example:

CDN-Cache-Control: public, s-maxage=3600
Content-Encoding: br
Vary: Accept-Encoding
X-Easel-Cache: HIT

The cache status describes whether the HTTP response was reused. The content encoding describes how the response body was transferred.

See Caching for cache eligibility and cache-control behavior.

Static files

Eligible static deployment files are compressed automatically.

This commonly includes:

/index.html
/assets/app.js
/assets/styles.css
/data/products.json
/images/logo.svg

No application configuration is required.

Content-hashed assets can still use long cache lifetimes independently from their compression behavior.

See Static files.

Dynamic responses

Responses returned from Easel Functions can also be compressed automatically.

For example:

export async function GET() {
  return Response.json({
    products: await loadProducts(),
  });
}

When the resulting JSON response is eligible, Easel can compress it before delivery.

Applications do not need to manually compress ordinary HTML, JSON, JavaScript, or text responses.

Streaming responses

Streaming responses can be compressed when the selected runtime and response path support streaming compression.

Easel forwards data as it becomes available rather than waiting for the complete response body before sending it.

Compression may add a small amount of buffering before the first compressed output is produced. For latency-sensitive streams, validate the behavior with a preview deployment.

Do not assume that every streaming format benefits from compression. Event streams with very small messages may trade reduced bandwidth for additional buffering.

Server-Sent Events

Server-Sent Events use:

Content-Type: text/event-stream

Compression behavior can affect when small event chunks become visible to the client.

For highly latency-sensitive event streams, explicitly test whether compression is appropriate. Compression may buffer small chunks before producing output.

Range requests

Range requests are not compressed and bypass the shared CDN cache.

Do not treat partial content (206) delivery as a supported feature for deployment static assets. Clients that send Range for those assets should not expect compressed or cacheable partial responses from Easel’s CDN path.

Content types

Compression eligibility depends partly on the response Content-Type.

Examples of commonly compressible types include:

text/html
text/css
text/plain
text/javascript
application/javascript
application/json
application/xml
image/svg+xml
application/wasm

Use a correct content type whenever possible.

A missing or incorrect Content-Type can prevent compression or cause the client to interpret the response incorrectly.

Custom compression

Most applications should rely on Easel’s automatic compression.

Manual compression may be appropriate when:

  • an upstream origin already provides a compressed representation
  • an application serves a custom precompressed format
  • a large static file is generated outside the normal build process
  • exact compression parameters are part of the application protocol

When manually compressing, ensure that:

  • the response body matches Content-Encoding
  • Vary: Accept-Encoding is present
  • the client supports the selected encoding
  • caches do not mix encoded and unencoded variants

Do not manually compress a response and then allow a framework or proxy to compress it a second time.

Verify compression

Use curl with automatic encoding negotiation:

curl --compressed -I https://example.com

A Brotli-compressed response may include:

HTTP/2 200
Content-Type: text/html; charset=utf-8
Content-Encoding: br
Vary: Accept-Encoding

Test gzip explicitly:

curl -I \
  -H "Accept-Encoding: gzip" \
  https://example.com

Test Brotli explicitly:

curl -I \
  -H "Accept-Encoding: br" \
  https://example.com

Test without compression support:

curl -I \
  -H "Accept-Encoding: identity" \
  https://example.com

Compare transferred sizes

Use curl to compare the response size with and without compression:

curl -sS \
  -H "Accept-Encoding: identity" \
  -o /dev/null \
  -w "Uncompressed: %{size_download} bytes\n" \
  https://example.com
curl -sS --compressed \
  -o /dev/null \
  -w "Compressed: %{size_download} bytes\n" \
  https://example.com

The exact savings depend on the response contents.

Text-heavy HTML, CSS, JavaScript, and JSON usually compress well. Images, archives, and video generally do not.

Troubleshooting

The response is not compressed

Check that:

  • the request includes Accept-Encoding: br or gzip
  • the response is larger than the minimum size
  • the response uses a supported content type
  • the response does not already include Content-Encoding
  • the request is not a range request
  • the format is expected to benefit from compression

Brotli is not selected

Confirm that the request advertises Brotli:

Accept-Encoding: br, gzip

Some clients, proxies, and development tools advertise only gzip.

The browser reports a decoding error

Check whether the application manually set:

Content-Encoding: gzip

or:

Content-Encoding: br

without actually encoding the response body.

Also check for double compression by an application framework or upstream proxy.

Different clients receive different body sizes

This is expected when clients advertise different compression support.

A Brotli-capable browser may receive a smaller response than a client that supports only gzip or no compression.

Compression appears to delay a stream

Compression can buffer small chunks before producing output.

Test the route with and without compression support from the client. For event streams or highly interactive responses, measure whether the savings outweigh any added buffering.