Enabling GZIP Response Compression with EnvoyFilter
How to enable GZIP compression of responses using EnvoyFilter
We recently decided to centralise all gzip compression for our 500 or so microservices into an EnvoyFilter. Why? You ask. Because:
- Some people added compression response filters to their apps, others didn't.
- Those who did implement compression response filters configured them differently (for example; min-compression-bytes, compression levels etc).
- We have some internal
content-typeresponses that are not compressed by default, but we want them to be, globally.
- Different languages, and frameworks, have different performance profiles when it comes to compression.
- We have other EnvoyFilters that inspect the response body from a service, that would not work if the service returned a compressed response.
So we strived for consistency. We run Envoy/Istio sidecars next to all of our application containers, so we decided to move this responsibility to there.
We opt'd to create an EnvoyFilter per-service, so that it was tied to their release pipeline for a more controlled rollout. However here i'm demonstrating applying it globally, without a workload selector and in the
We're using type.googleapis.com/envoy.extensions.filters.http.compressor.v3.Compressor type in order to do this, with the type.googleapis.com/envoy.extensions.compression.gzip.compressor.v3.Gzip compressor library.
applyTo section effetively injects this into the
SIDECAR_INBOUND filterChain for every sidecar on our mesh. It feels a bit backwards; because the compression actually happens on the
response of an inbound request. The configuration of that response can be seen under the
The other keys to draw attentiont to here are:
min_content_length. You'll need to experiment to find the optimal value for your configuration, and network. Remember that gzipping is a trade, less network for more CPU and potentially more latency.
remove_accept_encoding_header. This will ensure the
Accept-Encodingheader from the incoming request is removed. Otherwise your app's compression filter will handle it, rather than Envoy.
Not much to say, enjoy consistent compression implementation across your mesh! Any client that sends
Accept-Encoding: gzip will get a gzip response.