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"
    }
}

↑ back to index