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.
Table of Contents
- 1. Why the choice of compression method still matters
- 2. How Brotli and Zstd work under the hood
- 3. Compression ratio compared: HTML, CSS, JavaScript, and JSON
- 4. Encoding and decoding speed compared
- 5. Current browser support status for Zstd content encoding
- 6. Nginx configuration for Brotli
- 7. Nginx configuration for Zstd and running both methods in parallel
- 8. When a switch or parallel support actually pays off
- 9. A decision guide side by side
- 10. Summary
- 11. FAQ
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
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.