Lekértem curl-lel a saját blogom főoldalát, és a válaszban egy olyan fejléc jött vissza, amit sosem állítottam be: content-encoding: zstd. Rövid nyomozás után kiderült, hogy a Cloudflare ingyenes csomagja már alapból Zstandarddal tömörít. A poén az árlista túlsó végén van: a Pro és a Business ügyfelek brotlit kapnak alapértelmezésként, az Enterprise pedig – komolyan – gzipet. Minél többet fizetsz, annál patinásabb az algoritmus.
Ez elég jó ürügy volt, hogy megnézzem, hol tart a webes válasz-tömörítés 2026-ban. A rövid verzió: a zstd idén februárban vált ténylegesen univerzálissá a böngészőkben, a defaultok pedig – az nginx-től a Node-on át a CDN-ekig – szinte mindenhol mást csinálnak, mint amire számítanál.

A harmadik tömörítő
A Zstandardot a Meta fejlesztette (Yann Collet munkája, akit az lz4-ért is szerethetsz), és előbb a saját infrastruktúrájukban terítették szét mindenhová; az RFC 8878 2021-ben szabványosította. A webre viszont csak 2024-ben ért oda: a Chrome 123 2024 márciusában, a Firefox 126 két hónappal később kapcsolta be a Content-Encoding: zstd támogatását. A sort a WebKit zárta: a Safari 26.3 2026 februárjában – azzal a tipikus Apple-lábjegyzettel, hogy csak iOS 26.3-on és macOS Tahoe-n; a régebbi macOS-eken futó Safari kimarad.
A böngésződ tehát jó eséllyel ezt küldi minden egyes kéréssel: Accept-Encoding: gzip, deflate, br, zstd. Hogy érkezik-e rá zstd válasz, az már a szerveren múlik. A Meta értelemszerűen a saját főztjét eszi:
$ curl -sI -H 'Accept-Encoding: zstd' https://www.facebook.com/ | grep -i content-encoding
content-encoding: zstd
A defaultok, amikkel valójában élsz
Mielőtt mérnénk, érdemes tisztázni, mit csinálnak az eszközeid, ha nem szólsz rájuk. Az nginx gzip_comp_level defaultja nem a zlib-féle 6, hanem 1 – a lehető leggyengébb arány. A Node ezzel szemben a másik irányba lő túl: a zlib.brotliCompressSync() alapértelmezett minősége a BROTLI_DEFAULT_QUALITY, ami történetesen 11, vagyis a maximum. A zstd defaultja a szolid 3.
$ node -e "const z = require('node:zlib').constants; \
console.log(z.BROTLI_DEFAULT_QUALITY, z.ZSTD_CLEVEL_DEFAULT)"
11 3
Az Express világában népszerű compression middleware szerzői pontosan tudják, mit jelent ez: a kód kézzel állítja 4-re a brotli minőségét, egy sokatmondó kommenttel („set the default level to a reasonable value with balanced speed/ratio”). Ha viszont valaha írtál saját brotli-tömörítést Node-ban, és a defaultokra hagyatkoztál, akkor kérésidőben, maximális minőségen tömörítettél. Mindjárt látszik, az mennyire fáj.
Megmértem
Node 22.22.3, natív node:zlib, két valós payload: ennek a blognak a főoldala (103 KiB HTML) és a react-dom production bundle-je (503 KiB minifikált JS). Több futás mediánját mértem; a táblázat a react-dom számait mutatja:
| kódolás | méret | arány | tömörítés | kicsomagolás |
|---|---|---|---|---|
| gzip -1 (nginx default) | 114,5 KiB | 22,8% | 2,9 ms | 0,88 ms |
| gzip -6 (zlib default) | 90,3 KiB | 17,9% | 9,6 ms | 0,81 ms |
| gzip -9 | 89,6 KiB | 17,8% | 38,0 ms | 0,79 ms |
| brotli 4 | 93,6 KiB | 18,6% | 4,8 ms | 0,81 ms |
| brotli 11 (Node default) | 73,2 KiB | 14,6% | 717 ms | 0,77 ms |
| zstd 3 (default) | 98,7 KiB | 19,6% | 2,1 ms | 0,51 ms |
| zstd 12 | 83,0 KiB | 16,5% | 14,3 ms | 0,45 ms |
| zstd 19 | 75,4 KiB | 15,0% | 153 ms | 0,46 ms |
A brotli 11 sora a kedvencem: 717 ms CPU-idő egyetlen fél megás válaszért. Kérésenként. Ezt csinálja a Node defaultja, és ezért állítja át kézzel a compression middleware. A gzip -9 ugyanez kicsiben: négyszer annyi munka a -6-hoz képest 0,7 KiB nyereségért.
A statikus előtömörítés oldalán a brotli 11 továbbra is a méret királya, de a zstd 19 majdnem hozza ugyanazt az arányt ötödannyi időből. On-the-fly viszont a zstd 3 a mezőny legjobbja: az 500 kB-os bundle-ön gyorsabb volt, mint a gzip a legalacsonyabb szintjén, jobb aránnyal – és a kicsomagolása is 0,5 ms-ból megvan ott, ahol a gzipnek és a brotlinak 0,8 kell. A böngészőben ez mikroszekundumos tétel, de egy proxy vagy CDN, ami másodpercenként több ezer választ csomagol ki és újra, pontosan ezért szereti a zstd-t.
És egy részlet, amire nem számítottam: a brotli 4 a HTML-en megveri a gzip -6-ot (18,0% vs. 18,2%), a minifikált JS-en viszont kikap tőle (18,6% vs. 17,9%). Nem véletlen: a brotli magával hord egy 122 784 bájtos beépített szótárat (az RFC 7932 Appendix A-ja), amely webes szövegkorpuszból készült, és minden szavához 121 transzformációs alak tartozik. HTML-en ez alacsony szinten is sokat ad, minifikált kódon viszont alig – ott a brotli előnye csak a magas, drága szinteken jön vissza.
A 8 megás plafon
A zstd egyik nagy dobása az akár gigabájtos ablakméret – a weben ebből majdnem baleset lett. A Chromium 8 MiB-nál maximálta a dekódolási ablakot, és ha egy frame ennél többet kér, a letöltés ERR_ZSTD_WINDOW_SIZE_TOO_BIG hibával elszáll. A Kanidm felhasználói így kaptak üres oldalt a Chrome 123 után: a Rust-os tower-http régi verziója gond nélkül gyártott ekkora frame-eket, a projekt végül inkább kidobta a zstd-t. Azóta az RFC 9659 ezt szabállyá emelte: HTTP-ben az encoder nem adhat ki 8 MB-nál nagyobb ablakot igénylő frame-et. A szintekhez tartozó alapértelmezett ablakméretek beleférnek; a kézzel felcsavart windowLog és a CLI --long módja viszont pontosan ezt a hibát termeli.
Jó, de mivel szolgáljam ki?
Itt jön a hidegzuhany: az nginx-nek 2026-ban sincs hivatalos zstd modulja (közösségi létezik, ahogy a brotlihoz is külön modul kell). A Caddy natívan tudja az encode zstd gzip direktívával. Node-ban a 22.15.0 óta ott van a node:zlib-ben (zstdCompressSync és társai, egyelőre experimental jelöléssel). CDN-nél pedig jellemzően egy kapcsoló vagy compression rule az egész – ott tényleg nincs kifogás.
Hogy én mit csinálnék éles rendszerben? Ha CDN mögött ülsz, valószínűleg semmit: a tömörítés az edge dolga, és mint a saját blogom példája mutatja, már azelőtt zstd-t szolgálsz ki, hogy tudnál róla. Saját originnél statikus assetekre marad a build-time brotli 11 precompress gzip fallbackkel – a CPU-t ott egyszer fizeted meg, a méret meg a király –, és a zstd 19 akkor kerül képbe, ha a build ideje kezd fájni. Dinamikus válaszoknál (API, SSR HTML) viszont ma már a zstd 3 vagy a brotli 4 az értelmes default. Csak a Node-féle gyári brotlit ne: ha egy API-d hirtelen fél másodperces válaszidőket produkál, és valaki múlt héten „bekapcsolta a tömörítést”, most már tudod, hol kezdd a keresést. A gzip pedig marad, ami mindig is volt: a fallback, ami sosem hal meg – már csak az Enterprise-ügyfelek kedvéért sem.
Források
- MDN: Content-Encoding
- RFC 8878: Zstandard Compression · RFC 9659: Window Sizing for Zstandard Content Encoding · RFC 7932: Brotli
- Chrome Platform Status: Zstd Content-Encoding · Firefox 126 release notes · WebKit features in Safari 26.3
- Node.js zlib dokumentáció · nginx ngx_http_gzip_module
- Cloudflare: Content compression