[Nginx Best Practices] Gzip & Brotli Compression for Nginx

Configuring Gzip & Brotli Compression for Nginx

Configuring Gzip & Brotli compression on an Nginx web server running in Linux. Gzip & Brotli are the most popular compression algorithms supported by major web browsers.

  • Gzip compression Algorithm

Gzip provides a lossless compression, this means the original data can be recovered when decompressing it. It is based on the DEFLATE algorithm, which is a combination of LZ77 and Huffman coding.

  • Brotli compression Algorithm

Just like gzip, brotli is a lossless compression algorithm widely supported across many browsers. It is developed by Google and is best suited for compression of text-based static resources, like json, js,css, and html. We will use NGINX module for Brotli compression in this setup.

Gzip

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 2000;
gzip_types text/plain
application/json
application/javascript
application/x-javascript
text/css
application/xml
text/javascript
application/x-httpd-php
image/jpeg
image/gif
image/png;

gzip

1
2
3
4
Syntax:	gzip on | off;
Default:
gzip off;
Context: http, server, location, if in location

Enables or disables gzipping of responses.

gzip_buffers

1
2
3
4
Syntax:	gzip_buffers number size;
Default:
gzip_buffers 32 4k|16 8k;
Context: http, server, location

Sets the number and size of buffers used to compress a response. By default, the buffer size is equal to one memory page. This is either 4K or 8K, depending on a platform.

gzip_comp_level

1
2
3
4
Syntax:	gzip_comp_level level;
Default:
gzip_comp_level 1;
Context: http, server, location

Sets a gzip compression level of a response. Acceptable values are in the range from 1 to 9.

gzip_min_length

1
2
3
4
Syntax:	gzip_min_length length;
Default:
gzip_min_length 20;
Context: http, server, location

Sets the minimum length of a response that will be gzipped. The length is determined only from the “Content-Length” response header field.

1
2
3
4
Syntax:	gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...;
Default:
gzip_proxied off;
Context: http, server, location

Enables or disables gzipping of responses for proxied requests depending on the request and response. The fact that the request is proxied is determined by the presence of the “Via” request header field. The directive accepts multiple parameters:

  • off

    disables compression for all proxied requests, ignoring other parameters;

  • expired

    enables compression if a response header includes the “Expires” field with a value that disables caching;

  • no-cache

    enables compression if a response header includes the “Cache-Control” field with the “no-cache” parameter;

  • no-store

    enables compression if a response header includes the “Cache-Control” field with the “no-store” parameter;

  • private

    enables compression if a response header includes the “Cache-Control” field with the “private” parameter;

  • no_last_modified

    enables compression if a response header does not include the “Last-Modified” field;

  • no_etag

    enables compression if a response header does not include the “ETag” field;

  • auth

    enables compression if a request header includes the “Authorization” field;

  • any

    enables compression for all proxied requests.

gzip_types

1
2
3
4
Syntax:	gzip_types mime-type ...;
Default:
gzip_types text/html;
Context: http, server, location

Enables gzipping of responses for the specified MIME types in addition to “text/html”. The special value “*” matches any MIME type (0.8.29). Responses with the “text/html” type are always compressed.

gzip_vary

1
2
3
4
Syntax:	gzip_vary on | off;
Default:
gzip_vary off;
Context: http, server, location

Enables or disables inserting the “Vary: Accept-Encoding” response header field if the directives gzip, gzip_static, or gunzip are active.

Module ngx_http_gzip_module - http://nginx.org/en/docs/http/ngx_http_gzip_module.html

gzip_static Sending Compressed Files

To send a compressed version of a file to the client instead of the regular one, set the gzip_static directive to on within the appropriate context.

1
2
3
location / {
gzip_static on;
}

In this case, to service a request for /path/to/file, NGINX tries to find and send the file /path/to/file.gz. If the file doesn’t exist, or the client does not support gzip, NGINX sends the uncompressed version of the file.

Note that the gzip_static directive does not enable on-the-fly compression. It merely uses a file compressed beforehand by any compression tool. To compress content (and not only static content) at runtime, use the gzip directive.

1
2
3
4
Syntax:	gzip_static on | off | always;
Default:
gzip_static off;
Context: http, server, location

Enables (“on”) or disables (“off”) checking the existence of precompressed files. The following directives are also taken into account: gzip_http_version, gzip_proxied, gzip_disable, and gzip_vary.

Module ngx_http_gzip_static_module - http://nginx.org/en/docs/http/ngx_http_gzip_static_module.html

$gzip_ratio

achieved compression ratio, computed as the ratio between the original and compressed response sizes.

1
2
3
4
5
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';

access_log /spool/logs/nginx-access.log compression buffer=32k;

Remember to Reload NGINX to enable:

1
# nginx -t && nginx -s reload

Brotli

Install Brotli

Install the Brotli module.

For CentOS 8.x, Oracle Linux 8.x, and RHEL 8.x:

1
$ sudo yum install nginx-plus-module-brotli

For CentOS 6.x and 7.x:

1
2
3
$ sudo yum -y install https://extras.getpagespeed.com/release-latest.rpm

$ sudo yum -y install nginx nginx-module-nbr

For Debian 10 and Ubuntu::

1
$ sudo apt-get install nginx-plus-module-brotli

For SLES 15:

1
$ sudo zypper install nginx-plus-module-brotli

Put the load_module directives in the top‑level (“main”) context of NGINX Plus configuration file, nginx.conf:

1
2
3
4
# /etc/nginx/nginx.conf

load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

Remember to Reload NGINX to enable the module:

1
# nginx -t && nginx -s reload

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# brotli
brotli on;
brotli_comp_level 6;
brotli_min_length 1k;
brotli_types text/xml
image/svg+xml
application/x-font-ttf
image/vnd.microsoft.icon
application/x-font-opentype
application/json
font/eot
application/vnd.ms-fontobject
application/javascript
font/otf
application/xml
application/xhtml+xml
text/javascript
application/x-javascript
text/plain
application/x-font-truetype
application/xml+rss
image/x-icon
font/opentype
text/css
image/x-win-bitmap;

Suggested MIME type

A more complete MIME type list has been suggested here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
application/atom+xml
application/geo+json
application/javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/vnd.ms-fontobject
application/wasm
application/x-font-opentype
application/x-font-truetype
application/x-font-ttf
application/x-javascript
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
application/xml+rss
font/eot
font/opentype
font/otf
image/bmp
image/svg+xml
image/vnd.microsoft.icon
image/x-icon
image/x-win-bitmap
text/cache-manifest
text/calendar
text/css
text/javascript
text/markdown
text/plain
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy
text/xml

References

[1] Module ngx_http_gzip_module - http://nginx.org/en/docs/http/ngx_http_gzip_module.html

[2] The gzip home page - https://www.gzip.org/

[3] Module ngx_http_gzip_static_module - http://nginx.org/en/docs/http/ngx_http_gzip_static_module.html

[4] GitHub - google/brotli: Brotli compression format - https://github.com/google/brotli

[5] GitHub - google/ngx_brotli: NGINX module for Brotli compression - https://github.com/google/ngx_brotli

[6] How To Enable GZIP & Brotli Compression for Nginx on Linux | ComputingForGeeks - https://computingforgeeks.com/how-to-enable-gzip-brotli-compression-for-nginx-on-linux/

[7] NGINX Docs | Brotli - https://docs.nginx.com/nginx/admin-guide/dynamic-modules/brotli/

[8] NGINX Docs | Compression and Decompression - https://docs.nginx.com/nginx/admin-guide/web-server/compression/

[9] How to install NGINX Brotli module in CentOS/RedHat 6, 7 or 8 | by Danila Vershinin | Medium - https://medium.com/@getpagespeed/install-nginx-with-brotli-module-in-centos-redhat-7-82782f2e329f

[10] Supported file types list · Issue #32 · eustas/ngx_brotli · GitHub - https://github.com/eustas/ngx_brotli/issues/32#issuecomment-502964122