Brotli vs. Zstandard (Zstd): A Practical Compression Comparison
AI generated
60fps
ms
Performance · Compression · Web Server
Brotli vs. Zstandard: Compression Methods Compared
Compression ratio, speed, and browser support in a technical comparison

Brotli has established itself over the past few years as the preferred compression method for HTTP responses, replacing Gzip in most production setups because it produces noticeably smaller files for text content like HTML, CSS, and JavaScript. Zstandard, or Zstd, is now pushing into the web space as a second modern contender, originally built for file systems and network protocols where it stands out mainly for its speed. This article compares both methods soberly on compression ratio and speed, maps out the current browser support situation for Zstd as a content encoding, and shows how both methods can run side by side on the server.

15 min read Brotli · Zstd HTTP Compression

1. Why the choice of compression method still matters

The size of transferred bytes remains a direct lever on load time despite growing bandwidth, because mobile connections, congested Wi-Fi networks, and long round-trip times make the effect of smaller responses felt more strongly in practice than any bandwidth increase. An HTML document or JavaScript file that is several hundred kilobytes uncompressed can often be reduced to a fifth or a tenth of its original size by a modern text compression method, which has a direct effect on Time to First Byte and Largest Contentful Paint.

Gzip was the de facto standard for many years because virtually every browser and server supports it, but it achieves noticeably worse compression ratios than newer methods at comparable computational cost. Brotli closed that gap and is now widely deployed, while Zstandard enters the picture as an additional option whose strengths lie mainly in speed. For operators of online shops and content platforms, it is worth taking a close look at which method is the better choice for which use case.

2. How Brotli and Zstd work under the hood

Brotli combines an LZ77-based approach with Huffman coding and context modeling, and additionally ships a static, built-in dictionary of roughly 120 kilobytes of common text fragments drawn from HTML, CSS, JavaScript, and natural language. It is precisely this pretrained dictionary that gives Brotli an edge on typical web content, because recurring patterns like

, function(), or common English words are already known before the actual compression starts, rather than having to be learned from the document being compressed itself.

Zstandard follows a similar algorithmic foundation of entropy coding and dictionary search, but was built from the ground up for speed and offers a very wide range of compression levels, from 1 to 22. Zstd does not ship a fixed, web-specific default dictionary, but it does support training custom, project-specific dictionaries, which can provide a real advantage for many small, structurally similar responses such as JSON API payloads, an advantage a generic dictionary simply cannot offer.

3. Compression ratio compared: HTML, CSS, JavaScript, and JSON

At high compression levels, Brotli delivers a slightly better compression ratio than Zstd for classic web content like HTML and CSS files in most benchmarks at a comparable speed level, largely thanks to the built-in web dictionary. At Brotli quality level 11, the highest available, typical HTML documents can be compressed to a ratio that beats Gzip at its highest level by roughly 15 to 20 percent, while Zstd at its top level 22 lands roughly on par with Brotli, sometimes trailing it slightly.

The gap narrows for very large, highly repetitive files, because both methods then find enough context within the document itself to produce good results independent of any shipped dictionary. For small responses, such as short API payloads under ten kilobytes, a Zstd dictionary trained on the project's own data can actually beat Brotli on compression ratio, because it is tailored exactly to the real response format rather than to generic web content.

4. Encoding and decoding speed compared

The clearest difference between the two methods shows up not in compression ratio but in speed. Brotli at quality level 11 is computationally expensive and unsuitable for dynamic, per-request compression, because compression time for larger files can reach several hundred milliseconds. Zstd achieves noticeably shorter encoding times even at high compression levels and, at its lower levels, offers a range where usable compression ratios can be achieved at a fraction of Brotli's CPU cost.

For decompression, which happens in the browser and matters for perceived load time, Zstd is ahead by design, since decompression speed was a core goal of the format from the start. For static assets that are precompressed once at build time and then only ever served, encoding speed is practically irrelevant, which is why the highest Brotli quality level is almost always worth it in that case. For dynamically generated content that has to be compressed fresh on every request, Zstd at a medium compression level is often the more practical choice.

5. Current browser support status for Zstd content encoding

Brotli has been supported over HTTPS by all relevant browsers for years and can be deployed in production without hesitation, with a fallback mechanism being little more than a formality. For Zstandard as an HTTP content encoding the picture is more nuanced: Chromium-based browsers like Chrome and Edge have supported zstd content encoding since version 123, and Firefox followed with version 126, so support across the two most widely used browser engines can now be considered production ready.

Safari still lags behind on native Zstd content encoding support, which means the rollout cannot simply be flipped on across the board and instead has to be negotiated through the Accept-Encoding header sent by the client. A server offering Zstd must therefore still keep both Brotli and Gzip available as fallbacks, so clients without Zstd support do not end up receiving a response they cannot decode. This situation should keep improving with future browser versions, but it is currently an important reason why running Zstd alone, without a Brotli fallback, is not yet advisable.

6. Nginx configuration for Brotli

Brotli is not part of Nginx core and has to be added through the dynamic ngx_brotli module, either by compiling it in with the corresponding module flag or by using a prebuilt Nginx image that already ships the module. For static assets that were already precompressed into a .br file at build time, brotli_static enables serving the precompressed file directly, without the server having to compress at runtime, which saves CPU load and shortens response time.

For dynamically generated content where no precompressed file exists, runtime Brotli compression takes over, though usually at a lower quality level than at build time to keep server CPU load in check. The configuration below shows both cases combined, precompressed static files together with a moderate compression level for dynamic responses.


http {
    # Serve precompressed .br files directly when available
    brotli_static on;

    # Dynamic compression for responses without a precompressed file
    brotli on;
    brotli_comp_level 5;
    brotli_min_length 512;
    brotli_types
        text/plain
        text/css
        text/xml
        application/json
        application/javascript
        application/xml+rss
        image/svg+xml;
}

7. Nginx configuration for Zstd and running both methods in parallel

Zstandard support in Nginx likewise requires an additional module, such as ngx_http_zstd_module, which, analogous to ngx_brotli, offers both static serving of precompressed .zst files and dynamic runtime compression. To make sure each client gets the best format it can handle, Nginx evaluates the Accept-Encoding header sent by the client and automatically picks the best supported format in the order Zstd, then Brotli, then Gzip, provided all three modules are active at once.

The important part is configuring both a precompressed variant and a dynamic fallback for every supported format, so no client is left empty-handed. For static assets that means the build process needs to produce both a .br and a .zst variant of every file, which lengthens the build slightly but incurs no additional CPU cost at runtime, since Nginx simply serves the matching file.


http {
    # Zstd precompressed files and dynamic compression
    zstd_static on;
    zstd on;
    zstd_comp_level 12;
    zstd_min_length 512;
    zstd_types
        text/plain
        text/css
        application/json
        application/javascript
        image/svg+xml;

    # Negotiation order zstd, then brotli, then gzip
    # is determined by the client's Accept-Encoding header
}

8. When a switch or parallel support actually pays off

For most online shops and content sites, fully switching from Brotli to Zstd is not currently worthwhile, because Brotli still delivers a better compression ratio for static assets and is reliably supported by all relevant browsers. Running both in parallel makes more sense: Brotli at its highest quality level for precompressed static assets like CSS and JavaScript bundles, and Zstd for cases where compression speed genuinely matters, such as dynamically generated API responses under high request volume.

Zstd becomes especially worthwhile once servers are under heavy CPU load and dynamic content has to be recompressed on every request, because its shorter encoding times directly protect server capacity. For a project made up mostly of static, well cacheable assets, Brotli with precompressed files remains the simpler and more efficient solution, while parallel Zstd support pays off mainly where clients can already make use of it and server load is a genuine concern.

9. A decision guide side by side

The table below summarizes the key differences between Brotli and Zstd to help estimate more quickly, for a concrete project, which method is the better choice for which use case.

Criterion Brotli Zstandard (Zstd) Recommendation
Compression ratio (static, highest level) Very good, thanks to web dictionary Comparable, sometimes slightly behind Brotli for precompressed static assets
Encoding speed Slow at the highest level Noticeably faster at a similar ratio Zstd for dynamic, high-frequency content
Decoding speed in the browser Good Very good, a core design goal No practical difference for end users
Browser support (content encoding) Nearly universal Chrome/Edge since 123, Firefox since 126, Safari missing Always run with a Brotli/Gzip fallback
Custom dictionaries Fixed, generic for web content Trainable, project specific Zstd for many similar small JSON responses

Mironsoft

Web performance, Core Web Vitals, and load time optimization

Load times that don't make users bounce before the page is even visible?

We review existing websites for slow Core Web Vitals, bloated JavaScript bundles, and unnecessary render blockers, then build a performance foundation that stays measurable instead of just looking good once.

Performance Audit

Systematically measuring and fixing Core Web Vitals, load waterfall, and render blockers.

Bundle Optimization

Specifically reducing JavaScript and CSS bundle size and improving code splitting.

Monitoring Setup

Establishing continuous performance monitoring instead of a one-time snapshot.

10. Summary

Brotli vs. Zstd: The Essentials at a Glance

Core idea

Brotli and Zstd are not mutually exclusive, they fit different scenarios and can run side by side on the server with a clean fallback.

Compression ratio

For static web content Brotli usually edges ahead thanks to its built-in dictionary, while a trained Zstd dictionary can catch up for small, similar JSON responses.

Speed

Zstd is clearly faster at both encoding and decoding, which makes it attractive for dynamically compressed content under heavy server load.

Browser support

Chrome, Edge, and Firefox already support Zstd as a content encoding, Safari does not yet, so a Brotli fallback remains mandatory.

11. FAQ: Brotli vs. Zstd: The Essentials at a Glance

1Is Zstd faster than Brotli?
For both encoding and decoding, Zstd is faster than Brotli by design, especially at high compression levels. On pure compression ratio, Brotli usually edges ahead for typical web content.
2Should I replace Gzip entirely with Brotli or Zstd?
Gzip should be kept as a last-resort fallback for very old clients, but as a primary method it is outperformed by both Brotli and Zstd on compression ratio and speed and should no longer be actively prioritized.
3Do all browsers support Zstd as a content encoding?
No, Chrome and Edge have supported it since version 123, Firefox since version 126, Safari does not natively support it yet. A server must therefore still offer Brotli or Gzip as a fallback.
4Do I need a separate Nginx module for Brotli and Zstd each?
Yes, neither method is part of Nginx core. Brotli is added through ngx_brotli, Zstd through a module like ngx_http_zstd_module, either compiled in or provided by a prebuilt image.
5Is the highest Brotli quality level worth it for dynamic content?
Usually not, because compression time at level 11 is too high for dynamic responses. For dynamic content, either a lower Brotli level or Zstd at a medium compression level tends to work better.
6What is a project-specific Zstd dictionary?
A compression dictionary trained on typical responses from your own project, which can achieve a better compression ratio than a generic web dictionary for many structurally similar small responses like JSON APIs.
7Can I offer both Brotli and Zstd on the same server at once?
Yes, Nginx evaluates the client's Accept-Encoding header and automatically serves the best supported format, as long as both precompressed files and dynamic compression are configured for each method.
8Does supporting both methods in parallel add server load?
Not for static, precompressed assets, since Nginx simply serves the matching file. Dynamic compression of both formats does add computational overhead, which should be limited by using lower compression levels.
9Does Brotli make sense for images or already compressed formats?
No, images in JPEG or WebP format as well as already compressed archives barely benefit from additional text compression, and the file can sometimes even end up slightly larger.
10How do I make sure old browsers keep working?
By keeping Gzip available as a last fallback in the server configuration and letting negotiation happen automatically through the Accept-Encoding header, so every client receives the best format it supports.