Compression and Payload Size

JSON is the most compressible payload there is: repeated keys, repeated punctuation, ASCII digits. The compression (https://github.com/expressjs/compression 2,805 ) middleware negotiates gzip, deflate or br from the request's Accept-Encoding and streams the body through node:zlib; version 1.8.2 supports Brotli on every maintained Node release.

Compressing responses over 1 KBJavaScript
app.use(compression());                            // npm i compression; threshold 1kb
app.use(compression({ threshold: '4kb', filter: (req, res) => !res.getHeader('X-No-Zip') }));

The same 300-record list, requested with three different Accept-Encoding values:

One JSON list, four encodings, measured with autocannon 8,524 at 50 connections
Accept-Encoding Content-Encoding Bytes on the wire Throughput Avg latency
none (no middleware) identity 27,314 4,218 req/s 11.35 ms
identity identity 27,314 — —
gzip gzip 3,563 2,720 req/s 17.88 ms
br br 2,574 3,163 req/s 15.27 ms

Gzip removed 87% of the bytes and Brotli 91% — 27 KB down to 2.5 KB — while throughput fell from 4,218 to 2,720 requests per second with gzip. Brotli was faster than gzip here because the middleware defaults to a low Brotli quality level, at which the algorithm compresses better and cheaper than zlib's default level 6. The trade looks bad only over loopback, where bandwidth is free; over a 4G link the 24 KB you do not send saves the client far more than 2 ms of server CPU.

Leave the 1 KB threshold alone: compressing a 200-byte error body adds a header and a zlib stream for nothing. Do not compress twice — if nginx 75 has gzip on for proxied responses (Running Behind nginx), drop the middleware. And never compress a secret sitting next to attacker-controlled input, which is the BREACH attack: use filter to exclude routes that echo a query parameter beside a CSRF token.