Compression is one setting with a large and immediate effect on text - HTML, CSS, JavaScript, JSON, SVG. It has no effect on anything already compressed, and asking for it there costs CPU for nothing.

Turn it on

gzip on;
gzip_vary on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript
           text/xml application/xml image/svg+xml;

Level 5 is the useful middle. Level 9 costs noticeably more CPU for a percent or two, on every single request.

What NOT to compress

JPEG, PNG, WebP, MP4 and ZIP are already compressed. Running gzip over them makes the file very slightly LARGER and burns CPU doing it. Note that image/svg+xml is the exception - SVG is text.

Brotli, where it is available

brotli on;\nbrotli_comp_level 5;\nbrotli_types text/plain text/css application/json application/javascript image/svg+xml;

Brotli is typically 15-20% smaller than gzip on text. Keep gzip configured alongside: the browser says what it accepts and the server picks.

Check it is happening

curl -sI -H 'Accept-Encoding: gzip, br' https://yourdomain.com/ | grep -i content-encoding

No content-encoding header means nothing is being compressed - often because a proxy in front is stripping the request header.

gzip_min_length matters: compressing a 200-byte response costs more than it saves, because the header overhead is a fixed size. A kilobyte is a sensible floor.