I enabled Brotli compression in Nginx for a dynamically generated, but rarely changing resource.
My expectation was that when Nginx caches upstream responses, it will also cache the compression result. Thus, I assumed the CPU cost of enabling Brotli would be negligible. Instead, I see a performance impact, confirmed by perf top
to be related to Brotli.
I verified that caching to the upstream server works. However, Nginx stores in its cache only the uncompressed upstream requests. Because of that, it will have to run the costly Brotli compression for each request. That is the problem.
There are sources (relating to gzip compression) recommending to compress either in upstream, or if that is not an option to create a second Nginx to proxy the request through, which takes the role of upstream and does the compression. Both solutions are not very elegant.
Is there a way to make Nginx cache not only the uncompressed upstream requests, but the result of the compression as well?
Maybe I am overlooking some. Here is a simplified config:
proxy_cache_path /var/cache/nginx levels=1 keys_zone=my_config_cache:8M
inactive=60m use_temp_path=off;
server {
location = /foo {
proxy_pass http://test-upstream;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_ignore_headers Expires;
proxy_ignore_headers Cache-Control;
brotli on;
brotli_comp_level 11;
proxy_cache my_config_cache;
proxy_cache_valid 10s;
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
expires 60s;
}
}