http-zstd #
Our hardened fork of tokers/zstd-nginx-module — Zstandard compression filter for nginx and Angie. Typically beats gzip at comparable or faster speeds. Continuously fuzzed and run under ASAN/UBSAN; see our deep-dive what it does, bugs fixed and the zstd vs brotli vs zlib-ng comparison.
Source: our fork on GitHub
Read more: deep-dive article on deb.myguard.nl
Directives
zstd #
syntax: zstd on | off; · default: zstd off; · context: http, server, location, if in location
Enables or disables on-the-fly zstd compression for responses. Example: ---
zstd_buffers #
syntax: zstd_buffers number size; · default: zstd_buffers 2 <ZSTD_CStreamOutSize()>; (the size is libzstd's recommended streaming output unit, ~128 KB) · context: http, server, location
Configures the number and size of output buffers used during compression. The total buffer space is number × size. Increasing these values allows larger chunks to be accumulated before writing, potentially improving throughput at the cost of higher per-request memory usage. Example: ---
zstd_bypass #
syntax: zstd_bypass string ...; · default: — · context: http, server, location
Disables on-the-fly compression for the current request when at least one of the given string parameters evaluates to a non-empty value that is not "0". Each parameter is typically a variable (often driven by a map), so the decision is made per request rather than statically. > > > ---
zstd_bypass_vary #
syntax: zstd_bypass_vary field-name; · default: — · context: http, server, location
Appends field-name to the response Vary header on every response from the location (both the compressed and the bypassed-identity variant), so a shared cache keys on the request header that drives a header/cookie-based request header or cookie: The module emits this as an additional Vary header line; caches union all ---
zstd_comp_level #
syntax: zstd_comp_level level; · default: zstd_comp_level 3; · context: http, server, location
Sets the zstd compression level. Accepted values depend on the installed zstd library version: Choosing a level: For most web-serving workloads, levels 1–3 are recommended. Avoid high levels (> 9) in production unless responses are generated infrequently and cached. Example: ---
zstd_dict_file #
syntax: zstd_dict_file /path/to/dict; · default: — · context: http
Loads a pre-trained zstd dictionary for use during compression. Dictionaries can significantly improve compression ratios for small, structurally similar responses (e.g. JSON API responses). Example: ---
zstd_dict_file_unsafe #
syntax: zstd_dict_file_unsafe on | off (on/off flag); · context: http
Boolean directive — set to "on" or "off".
zstd_long #
syntax: zstd_long on | off; · default: zstd_long off; · context: http, server, location
Enables zstd long-distance matching (ZSTD_c_enableLongDistanceMatching). zstd keeps a secondary long-range hash table that finds repeated sequences far beyond the regular match window, which can meaningfully improve the compression ratio on large, internally repetitive bodies — concatenated JSON, HTML with repeated boilerplate, log dumps, sitemaps. Example:
zstd_max_cctx_memory #
syntax: zstd_max_cctx_memory size; · default: — (disabled, no budget enforced) · context: http, server, location
Requires: module built with -DZSTD_STATIC_LINKING_ONLY against libzstd ≥ 1.4.0 (the project's production and CI builds do; see Compatibility). Asserts at config load that the combined zstd parameters configured for the location (zstd_comp_level, zstd_window_log, zstd_long, zstd_target_cblock_size) do not need more than size bytes of parameters to lower. ---
zstd_max_length #
syntax: zstd_max_length length; · default: — (no limit) · context: http, server, location
Sets the maximum response size that will be compressed. The limit is enforced in two places: By default there is no upper limit. You may want to set one if very large responses (e.g. multi-megabyte file downloads) should bypass compression to avoid holding the worker process busy. Example: ---
zstd_min_length #
syntax: zstd_min_length length; · default: zstd_min_length 1024; · context: http, server, location
Sets the minimum response size (in bytes) required for compression to apply. The size is taken from the Content-Length response header; responses without Content-Length are always eligible. Example: ---
zstd_static #
syntax: zstd_static on | off | always; · default: zstd_static off; · context: http, server, location
Controls how pre-compressed .zst files are served. When set to on, the module sets r->gzip_vary = 1, which causes nginx to add a Vary: Accept-Encoding response header (controlled by gzip_vary). Enable gzip_vary on; alongside zstd_static on; to ensure correct caching by proxies and CDNs. Example: Pre-compress files with a matching level to your workload: ---
zstd_target_cblock_size #
syntax: zstd_target_cblock_size size; · default: — (disabled, uses ZSTD library defaults) · context: http, server, location
Requires: libzstd ≥ v1.5.6 Sets the target compressed block size for zstd frames. Controlling block size improves incremental response parsing, particularly in browsers where CSS/JavaScript in the response head must be available as soon as possible. Example: ---
zstd_types #
syntax: zstd_types mime-type ...; · context: http, server, location
When omitted, the default covers common textual web representations. If set explicitly, it follows nginx's usual type-directive behaviour: text/html is included along with the listed MIME types. Use * to match all MIME types. Example for a typical web application: ---
zstd_window_log #
syntax: zstd_window_log exponent; · default: — (disabled; zstd uses its level-derived default) · context: http, server, location
Caps the zstd compression window at 2^exponent bytes. zstd's per-request working memory is dominated by the window size (roughly the window plus match-table overhead), so without a cap a high compression level on large response bodies lets each concurrent request inflate the worker's resident memory unpredictably. Bounding window_log gives a Example: ---
Example
http {
zstd on;
zstd_comp_level 19; # would otherwise eat ~90 MB / request
zstd_max_cctx_memory 256m; # accepted: level 19 fits in 256 MB
}
server {
location /risky/ {
zstd_comp_level 22;
zstd_max_cctx_memory 64m; # REFUSED at config load:
# "the configured zstd parameters need ~833 MB of per-request
# compressor memory, which exceeds zstd_max_cctx_memory 64m;
# lower zstd_comp_level (currently 22), lower zstd_window_log,
# disable zstd_long, or raise the budget"
}
}