Gzip vs. Brotli und die tatsächlichen Tradeoffs zwischen Kompressionsrate und CPU-Overhead
Kompression lohnt sich für REST-APIs praktisch immer, weil JSON sich außergewöhnlich gut komprimieren lässt, die eigentliche Frage ist nur, welcher Algorithmus wo zum Einsatz kommt. Gzip ist die sichere, universelle Standardwahl, Brotli erreicht spürbar bessere Kompressionsraten, aber zu einem CPU-Preis, der sich nicht überall auszahlt.
Inhaltsverzeichnis
- 1. Warum Kompression bei REST-APIs überhaupt eine Rolle spielt
- 2. Gzip: der etablierte Standard
- 3. Brotli im Vergleich: höhere Kompressionsrate, höhere CPU-Kosten
- 4. Wann sich Brotli gegenüber Gzip wirklich lohnt
- 5. Konfiguration auf Webserver-Ebene vs. Anwendungsebene
- 6. Content-Encoding-Header und Content Negotiation
- 7. CPU-Overhead und Kompressionsstufen gegeneinander abwägen
- 8. Fallstricke bei bereits komprimierten Payloads
- 9. Gzip oder Brotli: die Entscheidung im Überblick
- 10. Zusammenfassung
- 11. FAQ
1. Warum Kompression bei REST-APIs überhaupt eine Rolle spielt
JSON-Antworten bestehen zu einem großen Teil aus sich wiederholenden Strukturen: gleiche Feldnamen in jedem Array-Element, ähnliche Werte, viel Textformatierung durch Anführungszeichen, Kommas und geschweifte Klammern. Diese Redundanz macht JSON zu einem Format, das sich außergewöhnlich gut komprimieren lässt, häufig lassen sich siebzig bis achtzig Prozent der ursprünglichen Größe einsparen, ohne dass der Client davon etwas mitbekommt, da die Dekompression transparent im HTTP-Client passiert.
Für APIs mit großen Listen-Antworten, mobilen Clients mit eingeschränkter Bandbreite oder hoher Request-Frequenz summiert sich dieser Effekt schnell zu spürbar geringerem Datenverkehr und kürzeren Ladezeiten. Kompression ist deshalb bei modernen REST-APIs praktisch immer aktiviert, die eigentliche Frage ist nicht ob, sondern mit welchem Algorithmus und auf welcher Ebene der Infrastruktur.
2. Gzip: der etablierte Standard
Gzip basiert auf dem DEFLATE-Algorithmus und ist seit den neunziger Jahren fester Bestandteil praktisch jedes HTTP-Clients und Webservers. Die Kompressionsstufe lässt sich zwischen 1 (schnell, geringe Kompressionsrate) und 9 (langsam, hohe Kompressionsrate) einstellen, wobei in der Praxis meist ein mittlerer Wert zwischen 4 und 6 als guter Kompromiss zwischen CPU-Kosten und erreichter Größenreduktion gewählt wird.
Der große Vorteil von Gzip ist seine nahezu universelle Unterstützung: Jeder Browser, jede Programmiersprache und praktisch jeder HTTP-Proxy kann Gzip ohne zusätzliche Konfiguration verarbeiten. Für Teams, die auf Nummer sicher gehen wollen und keine Sonderfälle bei älteren Clients riskieren möchten, bleibt Gzip deshalb die naheliegende Standardwahl, auch wenn modernere Algorithmen bessere Kompressionsraten erreichen.
3. Brotli im Vergleich: höhere Kompressionsrate, höhere CPU-Kosten
Brotli wurde von Google speziell für Web-Inhalte entwickelt und erreicht bei Text- und JSON-Inhalten in der Regel eine zehn bis zwanzig Prozent bessere Kompressionsrate als Gzip bei vergleichbarer Einstellung, unter anderem durch ein eingebautes, für Web-typische Inhalte optimiertes Wörterbuch. Der Kompressionsgrad reicht von 0 bis 11, wobei die höchsten Stufen deutlich mehr CPU-Zeit benötigen als das Gzip-Äquivalent.
Genau dieser CPU-Overhead bei hohen Qualitätsstufen ist der entscheidende Tradeoff: Für statische, einmal vorab komprimierte Assets spielt die benötigte CPU-Zeit keine Rolle, weil die Kompression beim Build oder Deploy passiert und nicht bei jeder einzelnen Anfrage. Für dynamisch generierte API-Antworten, die bei jeder Anfrage neu komprimiert werden müssen, kann eine hohe Brotli-Qualitätsstufe dagegen die Antwortzeit spürbar verschlechtern, besonders unter hoher gleichzeitiger Last.
# nginx.conf - Kompression für die REST-API
http {
gzip on;
gzip_types application/json application/javascript text/css;
gzip_comp_level 5;
gzip_min_length 512;
gzip_vary on;
brotli on;
brotli_types application/json application/javascript text/css;
brotli_comp_level 5;
brotli_min_length 512;
location /api/ {
# Dynamische Antworten: moderate Qualitätsstufe wegen CPU-Kosten
add_header Vary "Accept-Encoding";
}
location /static/ {
# Statische Assets: einmalig mit Qualitätsstufe 11 vorkomprimiert
brotli_static on;
gzip_static on;
}
}
4. Wann sich Brotli gegenüber Gzip wirklich lohnt
Die entscheidende Unterscheidung ist, ob ein Inhalt statisch oder dynamisch ist. Statische Assets wie JavaScript-Bundles, CSS-Dateien oder eine feste OpenAPI-Spezifikationsdatei ändern sich selten und können deshalb einmalig mit der höchsten Brotli-Qualitätsstufe (11) vorkomprimiert und als fertige .br-Datei ausgeliefert werden, die maximale Kompressionsrate kostet hier keine laufende CPU-Zeit.
Dynamische API-Antworten dagegen entstehen bei jeder Anfrage neu und müssen in Echtzeit komprimiert werden, hier ist eine niedrigere Brotli-Qualitätsstufe (etwa 4 bis 6) oder je nach Last sogar weiterhin Gzip die praktikablere Wahl. Ein pauschales Brotli ist immer besser ignoriert diesen fundamentalen Unterschied zwischen einmaliger Vorabkompression und wiederholter Live-Kompression unter Produktionslast.
5. Konfiguration auf Webserver-Ebene vs. Anwendungsebene
Kompression sollte in den allermeisten Fällen auf Webserver-Ebene konfiguriert werden, etwa direkt in Nginx über die Module gzip und brotli, statt in der PHP-Anwendung selbst. Der Webserver ist für diese Aufgabe optimiert, kann Kompression parallel zu anderen Anfragen effizient verarbeiten und entlastet den PHP-Prozess vollständig von dieser Arbeit, die ohnehin nichts mit Geschäftslogik zu tun hat.
Eine Kompression direkt in der Anwendung, etwa über PHPs eigene ob_gzhandler-Funktion, ist in der Regel nur dann sinnvoll, wenn kein Zugriff auf die Webserver-Konfiguration besteht, etwa bei bestimmten Shared-Hosting-Umgebungen. In einer selbst kontrollierten Infrastruktur mit Nginx oder einem vergleichbaren Reverse-Proxy gibt es praktisch keinen Grund, Kompression auf Anwendungsebene zu erzwingen, wenn der Webserver dieselbe Aufgabe effizienter erledigt.
6. Content-Encoding-Header und Content Negotiation
Ein Client signalisiert über den Accept-Encoding-Header, welche Kompressionsverfahren er verarbeiten kann, typischerweise Accept-Encoding: gzip, br, deflate. Der Server wählt daraufhin das für ihn beste unterstützte Verfahren aus und markiert die tatsächlich verwendete Kompression im Content-Encoding-Header der Antwort, etwa Content-Encoding: br. Fehlt dieser Header, geht der Client davon aus, dass die Antwort unkomprimiert vorliegt.
Wird die Antwort zusätzlich über einen HTTP-Cache oder CDN ausgeliefert, muss der Vary-Header zwingend Accept-Encoding enthalten, damit für Clients mit unterschiedlicher Kompressionsunterstützung nicht versehentlich dieselbe, für ein anderes Encoding komprimierte Version aus dem Cache ausgeliefert wird. Ein fehlender Vary-Header ist eine häufige Ursache für kaputte Antworten hinter CDNs, bei denen ein Client plötzlich eine Brotli-komprimierte Antwort erhält, obwohl er nur Gzip unterstützt.
7. CPU-Overhead und Kompressionsstufen gegeneinander abwägen
Der praktische Kompromiss zwischen Kompressionsrate und CPU-Kosten lässt sich am besten über konkrete Kompressionsstufen statt über eine pauschale mehr ist besser Regel steuern. Für dynamische API-Antworten unter Produktionslast liefert Gzip-Stufe 5 oder 6 meist das beste Verhältnis aus erreichter Größenreduktion und CPU-Zeit pro Anfrage, während Stufe 9 kaum noch zusätzliche Ersparnis bringt, aber deutlich mehr Rechenzeit kostet.
Bei Brotli gilt ein ähnliches Muster: Stufe 4 bis 6 ist für dynamische, häufig wechselnde Inhalte ein sinnvoller Bereich, während Stufe 10 oder 11 ausschließlich für einmalig komprimierte, statische Inhalte reserviert bleiben sollte. Wer diese Differenzierung nicht vornimmt und pauschal die höchste Qualitätsstufe für alles verwendet, riskiert unter Last spürbar höhere Antwortzeiten, ohne dass der zusätzliche Kompressionsgewinn den Nutzer tatsächlich erreicht.
8. Fallstricke bei bereits komprimierten Payloads
Ein häufig übersehener Fallstrick betrifft JSON-Antworten, die bereits komprimierte Binärdaten enthalten, etwa Bilder oder PDFs, die als Base64-String direkt in ein JSON-Feld eingebettet wurden. Bilddaten in Formaten wie JPEG oder PNG sind selbst bereits stark komprimiert, eine erneute Gzip- oder Brotli-Kompression bringt hier kaum messbare Größenreduktion, kostet aber trotzdem die volle CPU-Zeit für den Kompressionsversuch.
Die sinnvollere Lösung ist, Binärdaten wie Bilder gar nicht erst als Base64 in eine JSON-Antwort einzubetten, sondern stattdessen eine separate URL zum Binärobjekt zurückzugeben, die eigenständig und ohne den Base64-Overhead von etwa dreiunddreißig Prozent zusätzlicher Größe ausgeliefert wird. Muss Base64 aus Kompatibilitätsgründen dennoch eingebettet werden, lohnt es sich, die Kompression für diese spezifischen Antworten gezielt zu deaktivieren oder auf eine niedrige Stufe zu reduzieren, um unnötige CPU-Last zu vermeiden.
9. Gzip oder Brotli: die Entscheidung im Überblick
Die Wahl zwischen Gzip und Brotli hängt in erster Linie davon ab, ob ein Inhalt statisch oder dynamisch ist, und wie viel CPU-Budget für Kompression unter Last tatsächlich zur Verfügung steht. Die folgende Tabelle fasst die wichtigsten Entscheidungskriterien zusammen.
| Kriterium | Gzip | Brotli | Empfehlung |
|---|---|---|---|
| Kompressionsrate bei Text/JSON | Gut | Ca. 10-20 % kleiner | Brotli bei ausreichendem CPU-Budget |
| CPU-Overhead bei hoher Qualitätsstufe | Moderat | Deutlich höher | Gzip für dynamische Antworten unter Last |
| Client-Unterstützung | Nahezu universell | Sehr weit verbreitet, vereinzelt fehlend | Gzip als Fallback konfigurieren |
| Eignung für statische Assets | Gut | Sehr gut bei Vorabkompression | Brotli Qualitätsstufe 11 offline für Assets |
| Eignung für dynamische API-Antworten | Sehr gut, geringe Latenz | Gut bei niedriger Qualitätsstufe | Gzip Stufe 5-6 als API-Standard |
Mironsoft
OpenAPI-Design, Symfony-APIs und API-Sicherheit
APIs, die externe Teams ohne Rückfragen integrieren können?
Wir prüfen bestehende REST-APIs auf inkonsistente Fehlerformate, fehlende OpenAPI-Dokumentation und Sicherheitslücken und bauen daraus eine API, die klar dokumentiert, versioniert und gegen Missbrauch abgesichert ist.
API-Review
OpenAPI-Spezifikation, Fehlerformate und Statuscodes auf Konsistenz prüfen.
Symfony-Umsetzung
DTOs, Serializer und Validator für saubere, typsichere Request/Response-Modelle einsetzen.
Security-Audit
Rate-Limiting, Auth-Schemes und Input-Validierung gegen echte Angriffsflächen absichern.
10. Zusammenfassung
Gzip vs. Brotli: Das Wichtigste auf einen Blick
Kernproblem
JSON komprimiert sich hervorragend, aber hohe Kompressionsstufen kosten spürbar CPU-Zeit, besonders bei dynamisch generierten Antworten.
Gzip vs. Brotli
Brotli erreicht bei Text meist 10 bis 20 Prozent bessere Kompressionsraten als Gzip, zum Preis eines deutlich höheren CPU-Overheads bei hohen Qualitätsstufen.
Konfigurationsebene
Kompression gehört auf Webserver-Ebene (Nginx), nicht in die Anwendung, damit der PHP-Prozess vollständig entlastet bleibt.
Praktischer Rat
Statische Assets mit Brotli Stufe 11 vorkomprimieren, dynamische API-Antworten mit Gzip Stufe 5-6 oder niedriger Brotli-Stufe live komprimieren.