Response-Kompression in REST-APIs: Gzip vs. Brotli und die tatsächlichen Tradeoffs
AI generated
{ }
GET
REST · Performance · Infrastruktur
Response-Kompression in REST-APIs
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.

14 Min. Lesezeit Gzip · Brotli Nginx · Content-Encoding

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.

11. FAQ: Gzip vs. Brotli: Das Wichtigste auf einen Blick

1Ist Brotli generell die bessere Wahl als Gzip?
Nicht generell. Für statische, vorab komprimierte Inhalte ja, für dynamische API-Antworten unter hoher Last kann der CPU-Overhead hoher Brotli-Qualitätsstufen die Vorteile wieder aufheben.
2Sollte ich Kompression in PHP oder im Webserver konfigurieren?
Im Webserver, etwa in Nginx. Das entlastet den PHP-Prozess vollständig und der Webserver ist für diese Aufgabe optimiert.
3Was bedeutet der Content-Encoding-Header konkret?
Er teilt dem Client mit, welches Kompressionsverfahren tatsächlich für die Antwort verwendet wurde, zum Beispiel gzip oder br, damit der Client sie korrekt dekomprimieren kann.
4Warum brauche ich den Vary-Header bei Kompression?
Ohne Vary: Accept-Encoding kann ein Cache oder CDN eine für ein bestimmtes Encoding komprimierte Antwort fälschlicherweise an einen Client mit anderer Kompressionsunterstützung ausliefern.
5Lohnt sich Kompression für kleine JSON-Antworten?
Kaum. Bei sehr kleinen Payloads überwiegt der CPU- und Header-Overhead häufig den Größengewinn, ein sinnvoller Mindestwert (min_length) verhindert unnötige Kompressionsversuche.
6Warum bringt Kompression bei Bildern in Base64 kaum etwas?
Weil Bildformate wie JPEG oder PNG bereits selbst komprimiert sind. Eine erneute Kompression auf Base64-kodierte Bilddaten reduziert die Größe kaum, kostet aber trotzdem CPU-Zeit.
7Welche Kompressionsstufe ist für dynamische APIs sinnvoll?
Meist Gzip-Stufe 5 bis 6 oder eine niedrige Brotli-Stufe zwischen 4 und 6, als Kompromiss zwischen Größenreduktion und CPU-Kosten pro Anfrage.
8Muss ich Gzip als Fallback zu Brotli anbieten?
Ja, da Brotli-Unterstützung zwar sehr weit verbreitet, aber nicht bei jedem Client oder älteren Proxys garantiert ist. Der Server sollte anhand des Accept-Encoding-Headers automatisch das passende Verfahren wählen.
9Wie komprimiere ich statische Assets am effizientesten?
Einmalig beim Build oder Deploy mit der höchsten Brotli-Qualitätsstufe vorkomprimieren und als fertige .br-Datei ausliefern, statt bei jeder Anfrage live zu komprimieren.
10Beeinflusst Kompression die Latenz spürbar?
Bei angemessener Kompressionsstufe kaum, da die eingesparte Übertragungszeit den zusätzlichen CPU-Aufwand meist übersteigt. Bei zu hoch gewählten Qualitätsstufen unter Last kann sich das allerdings umkehren.