Nginx-Geschwindigkeit steigern: Wesentliche Puffer, Komprimierung und Caching-Tipps

Entfesseln Sie die Spitzenleistung von Nginx mit diesem essenziellen Leitfaden zur Pufferoptimierung, Gzip-Komprimierung und intelligenten Caching-Strategien. Erfahren Sie, wie Sie Client- und Proxy-Puffer für effiziente Datenverarbeitung konfigurieren, eine robuste Inhaltskomprimierung zur Bandbreitenreduzierung implementieren und sowohl Browser- als auch Nginx-Proxy-Caching für blitzschnelle Antwortzeiten nutzen. Gespickt mit praktischen Nginx-Konfigurationsbeispielen und Best Practices bietet dieser Artikel umsetzbare Einblicke, um die Geschwindigkeit und Effizienz Ihres Webservers erheblich zu steigern.

Nginx-Geschwindigkeit steigern: Wesentliche Puffer, Komprimierung und Caching-Tipps

Nginx ist von Haus aus schnell, aber die Standardeinstellungen sind bewusst konservativ. Sie funktionieren für eine kleine Website, einen Testserver oder einen Reverse-Proxy mit bescheidenem Traffic. Sie sind nicht immer die beste Wahl, sobald Sie große Cookies, langsame Upstreams, große API-Antworten oder statische Assets verarbeiten, die tausendmal pro Stunde heruntergeladen werden.

Die nützliche Optimierung läuft meist auf drei Bereiche hinaus: Puffer, Komprimierung und Caching. Puffer entscheiden, ob Nginx Anfrage- und Antwortdaten im Speicher halten oder auf temporäre Dateien auslagern muss. Komprimierung entscheidet, wie viele textbasierte Daten Sie über das Netzwerk senden. Caching entscheidet, ob Nginx und der Browser vermeiden können, dieselbe Arbeit erneut zu leisten. Keine dieser Einstellungen ist magisch. Eine schlechte Cache-Regel kann private Inhalte preisgeben, und überdimensionierte Puffer können Speicher verschwenden. Das Ziel ist es, bewusst zu optimieren, mit Ihrem tatsächlichen Traffic-Muster zu testen und die Konfiguration lesbar genug zu halten, dass die nächste Person darüber nachdenken kann.

Optimierung von Nginx-Puffern für effiziente Datenverarbeitung

Nginx verwendet verschiedene Puffer, um Daten während der Anfrage- und Antwortverarbeitung temporär zu speichern. Die richtige Dimensionierung dieser Puffer ist entscheidend für die Leistung. Falsch dimensionierte Puffer können entweder zu übermäßigem Speicherverbrauch oder häufigen Festplattenschreibvorgängen (Spooling) führen, was beides die Leistung beeinträchtigt. Wir betrachten clientbezogene Puffer und Proxy-/FastCGI-Puffer.

Clientbezogene Puffer

Diese Puffer verwalten die Daten, die vom Client zu Nginx kommen.

  • client_body_buffer_size: Diese Direktive legt die Größe des Puffers zum Lesen des Client-Anfragekörpers fest. Wenn ein Anfragekörper diese Größe überschreitet, wird er in eine temporäre Datei auf der Festplatte geschrieben. Dies verhindert zwar Speicherüberlastung bei großen Uploads, aber häufige Festplattenschreibvorgänge können die Leistung verlangsamen.

    • Tipp: Für typische Webanwendungen, die keine sehr großen Datei-Uploads über POST-Anfragen verarbeiten, sind 8k oder 16k oft ausreichend. Erhöhen Sie den Wert, wenn Sie größere Formulare oder kleine Datei-Uploads direkt über Nginx verarbeiten.
    http {
        client_body_buffer_size 16k;
        # ...
    }
    
  • client_header_buffer_size: Definiert die Puffergröße zum Lesen des Client-Anfrageheaders. Für jede Verbindung wird ein einzelner Puffer zugewiesen.

    • Tipp: 1k ist der Standard und normalerweise für die meisten Header ausreichend. Erhöhen Sie ihn nur, wenn Sie Fehler wie "client sent too large header" erhalten, die oft auf viele Cookies oder komplexe Authentifizierungsheader zurückzuführen sind.
    http {
        client_header_buffer_size 1k;
        # ...
    }
    
  • large_client_header_buffers: Diese Direktive legt die maximale Anzahl und Größe der Puffer fest, die zum Lesen großer Client-Anfrageheader verwendet werden. Wenn der Header client_header_buffer_size überschreitet, versucht Nginx, Puffer mit dieser Direktive zuzuweisen.

    • Tipp: 4 8k (4 Puffer zu je 8 KB) ist eine übliche Einstellung. Passen Sie sie an, wenn Sie nach der Erhöhung von client_header_buffer_size weiterhin Header-Fehler sehen.
    http {
        large_client_header_buffers 4 8k;
        # ...
    }
    

Proxy- und FastCGI-Puffer

Diese Puffer verwalten Daten, wenn Nginx als Reverse-Proxy fungiert oder mit einem FastCGI-Backend (wie PHP-FPM) kommuniziert.

Wenn Nginx Anfragen weiterleitet, empfängt es die Antwort vom Backend-Server in Teilen und puffert sie, bevor er sie an den Client sendet. Dies ermöglicht es Nginx, langsame Backend-Antworten zu verarbeiten, ohne die Client-Verbindung zu blockieren.

  • proxy_buffer_size: Die Größe des Puffers für den ersten Teil der Antwort, die vom Proxy-Server empfangen wird. Dieser enthält normalerweise den Antwort-Header.

  • proxy_buffers: Definiert die Anzahl und Größe der Puffer, die zum Lesen der Antwort vom Proxy-Server verwendet werden.

  • proxy_busy_buffers_size: Legt die maximale Größe der Puffer fest, die zu einem bestimmten Zeitpunkt aktiv (beschäftigt) sein können, entweder beim Senden von Daten an den Client oder beim Lesen vom Backend. Dies hilft, zu verhindern, dass Nginx zu viel Speicher verbraucht, indem es Puffer zu lange hält.

    • Beispiel für Proxy Pass: Für eine typische Webanwendung könnte proxy_buffer_size der erwarteten Headergröße entsprechen, und proxy_buffers können so eingestellt werden, dass durchschnittliche Inhaltsgrößen ohne Festplattenschreibvorgänge verarbeitet werden.
    http {
        proxy_buffer_size          128k;
        proxy_buffers              4 256k; # 4 Puffer, je 256 KB
        proxy_busy_buffers_size    256k;
        # ...
    }
    
  • fastcgi_buffer_size, fastcgi_buffers, fastcgi_busy_buffers_size: Diese Direktiven funktionieren identisch zu ihren proxy_-Gegenstücken, gelten aber speziell für Antworten von FastCGI-Servern.

    • Beispiel für FastCGI: Hier gilt eine ähnliche Logik, passen Sie sie an die Antwortgrößen Ihrer PHP-/FastCGI-Anwendung an.
    http {
        fastcgi_buffer_size        128k;
        fastcgi_buffers            4 256k;
        fastcgi_busy_buffers_size  256k;
        # ...
    }
    

Warnung: Wenn Sie die Puffer zu groß einstellen, verbrauchen Sie mehr RAM pro Verbindung, was bei vielbesuchten Servern schnell den Speicher erschöpfen kann. Wenn Sie sie zu klein einstellen, schreibt Nginx temporäre Dateien auf die Festplatte, was zu I/O-Overhead führt. Überwachen Sie den Speicher und die Festplatten-I/O Ihres Servers, um die optimale Balance zu finden.

Aktivieren effektiver Komprimierung mit Gzip

Inhaltskomprimierung, hauptsächlich mit Gzip, kann die Größe der übertragenen Daten erheblich reduzieren, was zu schnelleren Seitenladezeiten und geringerem Bandbreitenverbrauch führt. Das gzip-Modul von Nginx ist hochgradig konfigurierbar.

Wesentliche Gzip-Direktiven

Fügen Sie diese Direktiven innerhalb Ihres http-Blocks oder eines bestimmten server- oder location-Blocks hinzu.

  • gzip on;: Aktiviert die Gzip-Komprimierung.

  • gzip_types: Gibt die MIME-Typen an, die komprimiert werden sollen. Nur bestimmte textbasierte Typen profitieren erheblich von der Komprimierung.

    • Best Practice: Fügen Sie gängige Webtypen hinzu, vermeiden Sie jedoch die Komprimierung von Bildern (image/*), Videos (video/*) und bereits komprimierten Dateien (.zip, .rar, .gz), da dies CPU-Zyklen ohne Nutzen verschwendet.
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
    
  • gzip_proxied: Aktiviert die Komprimierung für weitergeleitete Anfragen basierend auf Antwort- und Anfragebedingungen. Es ist hauptsächlich nützlich, wenn Nginx vor einem Anwendungsserver oder einem anderen Proxy sitzt.

    • any: Komprimiert weitergeleitete Antworten, wenn sie ansonsten qualifizieren.
    • no-cache, no-store, private, expired, auth: Komprimiert nur, wenn die Antwort oder Anfrage diese Bedingungen erfüllt. Diese Token sind keine "Nicht komprimieren"-Flags; sie sind Bedingungen, die die Komprimierung für weitergeleitete Antworten erlauben.
    gzip_proxied any;
    
  • gzip_min_length: Legt die Mindestlänge eines Antwortkörpers fest, den Nginx komprimieren wird. Kleine Dateien profitieren nicht stark von der Komprimierung und können durch den Komprimierungs-Overhead sogar größer werden.

    • Tipp: Ein Wert wie 1000 Bytes (1 KB) oder 256 Bytes ist ein guter Ausgangspunkt.
    gzip_min_length 1000;
    
  • gzip_comp_level: Legt die Komprimierungsstufe (1-9) fest. Höhere Stufen bieten eine bessere Komprimierung, verbrauchen aber mehr CPU-Ressourcen. Niedrigere Stufen sind schneller, komprimieren aber weniger effektiv.

    • Tipp: 4-6 ist für die meisten Server ein guter Kompromiss zwischen Komprimierungsrate und CPU-Auslastung.
    gzip_comp_level 5;
    
  • gzip_vary on;: Teilt Proxys mit, sowohl komprimierte als auch unkomprimierte Versionen einer Datei zwischenzuspeichern, abhängig vom Accept-Encoding-Header, den der Client sendet. Dies ist entscheidend für ordnungsgemäßes Caching und Auslieferung.

    gzip_vary on;
    
  • gzip_disable: Deaktiviert die Komprimierung für bestimmte Browser oder User Agents, die Probleme mit Gzip haben könnten.

    gzip_disable "MSIE [1-6]\."; # Beispiel: für alten Internet Explorer deaktivieren
    

Überlegungen: Obwohl Gzip sehr vorteilhaft ist, verbraucht die Komprimierung CPU-Zyklen. Für statische Dateien, die direkt von der Festplatte bereitgestellt werden (z. B. vorkomprimierte .gz-Dateien), kann Nginx sie direkt ohne erneute Komprimierung ausliefern, was noch effizienter ist. Für dynamische Inhalte ist Gzip in der Regel ein Nettogewinn.

Implementierung intelligenter Caching-Strategien

Caching ist wohl der effektivste Weg, um die Webserver-Leistung zu verbessern, indem die Notwendigkeit reduziert wird, Inhalte neu zu generieren oder erneut abzurufen. Nginx unterstützt sowohl Browser-seitiges (Client-seitiges) als auch Server-seitiges (Proxy-)Caching.

Browser-Caching (HTTP-Header)

Browser-Caching verlässt sich auf HTTP-Header, um Client-Browsern mitzuteilen, wie lange sie statische Assets speichern sollen. Dies verhindert wiederholte Downloads von unveränderlichen Ressourcen wie Bildern, CSS- und JavaScript-Dateien.

  • expires: Eine einfache Direktive zum Setzen der Expires- und Cache-Control: max-age-Header.

    location ~* \.(jpg|jpeg|gif|png|webp|ico|css|js|woff|woff2|ttf|otf|eot)$ {
        expires 365d; # Ein Jahr lang cachen
        add_header Cache-Control "public, no-transform";
        # Optional: Logs für statische Dateien deaktivieren
        access_log off;
        log_not_found off;
    }
    
  • add_header Cache-Control: Bietet eine detailliertere Kontrolle über Caching-Richtlinien. Übliche Werte sind:

    • public: Von jedem Cache zwischenspeicherbar (Browser, Proxy).
    • private: Nur vom privaten Cache des Clients zwischenspeicherbar (z. B. Browser).
    • no-cache: Muss vor der Verwendung mit dem Server erneut validiert werden, kann aber eine Kopie speichern.
    • no-store: Gar nicht cachen.
    • max-age=<Sekunden>: Gibt an, wie lange eine Ressource als frisch gilt.
  • Bedingte Anfragen (Etag und If-Modified-Since): Nginx behandelt Etag- und Last-Modified-Header für statische Dateien automatisch, sodass Browser bedingte Anfragen (If-None-Match oder If-Modified-Since) senden können. Wenn sich der Inhalt nicht geändert hat, antwortet Nginx mit einem 304 Not Modified, was Bandbreite spart.

Nginx-Proxy-Caching

Nginx kann als leistungsstarker Caching-Reverse-Proxy fungieren. Wenn es aktiviert ist, speichert Nginx Kopien von Antworten von Backend-Servern und stellt sie direkt an Clients aus, wodurch die Last auf Ihrem Backend erheblich reduziert wird.

1. Definieren einer Cache-Zone

Dies muss im http-Block erfolgen. proxy_cache_path definiert das Verzeichnis für den Cache, Speicherzonenparameter und andere Einstellungen.

http {
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=1g;
    # levels=1:2: Erstellt eine zweistufige Verzeichnishierarchie für Cache-Dateien (z. B. /var/cache/nginx/c/29/...). Hilft bei der Verteilung der Dateien.
    # keys_zone=my_cache:10m: Definiert eine gemeinsame Speicherzone namens 'my_cache' von 10 MB zum Speichern von Cache-Schlüsseln und Metadaten. Dies ist entscheidend für schnelle Nachschlagevorgänge.
    # inactive=60m: Zwischengespeicherte Elemente, auf die 60 Minuten lang nicht zugegriffen wurde, werden von der Festplatte entfernt.
    # max_size=1g: Legt die maximale Größe des Caches auf der Festplatte fest. Bei Überschreitung entfernt Nginx die am wenigsten verwendeten Daten.
    # ...
}

2. Aktivieren des Cachings für einen Ort

Innerhalb eines server- oder location-Blocks aktivieren Sie den Cache und definieren sein Verhalten.

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://backend_upstream; # Oder http://127.0.0.1:8000;
        proxy_cache my_cache; # Verwenden Sie die oben definierte Cache-Zone
        proxy_cache_valid 200 302 10m; # Erfolgreiche Antworten (200, 302) für 10 Minuten cachen
        proxy_cache_valid 404 1m;      # 404-Antworten für 1 Minute cachen
        proxy_cache_revalidate on;     # If-Modified-Since- und If-None-Match-Header zur Revalidierung verwenden
        proxy_cache_min_uses 1;       # Nur cachen, wenn ein Element mindestens einmal angefordert wurde
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
                                       # Veraltete Inhalte ausliefern, wenn das Backend nicht verfügbar ist oder aktualisiert wird

        # Einen Header hinzufügen, um zu sehen, ob die Antwort zwischengespeichert wurde
        add_header X-Cache-Status $upstream_cache_status;

        # Optional: Cache für bestimmte Bedingungen umgehen
        # proxy_cache_bypass $http_pragma $http_authorization;
        # proxy_no_cache $http_pragma $http_authorization;
    }
}

Wichtige Cache-Direktiven

  • proxy_cache_valid: Definiert Caching-Regeln basierend auf HTTP-Statuscodes und Dauer. Sie können mehrere Regeln angeben.

  • proxy_cache_revalidate on;: Ermöglicht Nginx die Verwendung von If-Modified-Since- und If-None-Match-Headern, wenn überprüft wird, ob zwischengespeicherte Inhalte noch frisch sind. Dies ist effizienter, als einfach den Cache ablaufen zu lassen.

  • proxy_cache_use_stale: Eine leistungsstarke Direktive, die Nginx anweist, veraltete (abgelaufene) Inhalte aus dem Cache auszuliefern, wenn das Backend nicht verfügbar oder langsam ist. Dies verbessert die Benutzererfahrung bei Backend-Problemen erheblich.

  • proxy_cache_bypass / proxy_no_cache: Verwenden Sie diese, um Bedingungen zu definieren, unter denen der Cache umgangen werden soll (z. B. für authentifizierte Anfragen oder bestimmte Abfrageparameter).

    # Beispiel, um Anfragen mit bestimmten Abfrageparametern oder Cookies nicht zu cachen
    # if ($request_uri ~* "(\?|&)nocache") { set $no_cache 1; }
    # if ($http_cookie ~* "SESSIONID") { set $no_cache 1; }
    # proxy_cache_bypass $no_cache;
    # proxy_no_cache $no_cache;
    

Cache leeren

Um den Nginx-Cache manuell zu leeren, können Sie einfach die Dateien im proxy_cache_path-Verzeichnis löschen. Für eine kontrolliertere Invalidierung sollten Sie die Verwendung eines Moduls wie ngx_cache_purge oder die Konfiguration eines bestimmten location zur Behandlung von Cache-Invalidierungsanfragen in Betracht ziehen.

Warnung: Falsch konfiguriertes Proxy-Caching kann dazu führen, dass Benutzer veraltete Inhalte sehen. Testen Sie Ihre Caching-Strategie immer gründlich in einer Staging-Umgebung, bevor Sie sie in der Produktion einsetzen. Stellen Sie sicher, dass dynamische Inhalte, die sich häufig ändern oder benutzerspezifisch sind, nicht aggressiv zwischengespeichert werden.

Ein praktischer Rollout-Plan

Der sicherste Weg, Nginx zu optimieren, besteht darin, jeweils eine Ebene zu ändern. Beginnen Sie mit Headern und statischen Assets, da das Risiko gering und der Nutzen leicht erkennbar ist. Fügen Sie lange Browser-Cache-Lebensdauern nur für versionierte Dateien hinzu, wie /app.8f3a2c.js oder /styles.2025-11-02.css. Wenn sich Ihre Asset-Namen nicht ändern, wenn sich die Datei ändert, cachen Sie sie nicht für ein Jahr. Verwenden Sie einen kürzeren expires-Wert oder korrigieren Sie zuerst die Build-Pipeline.

Als nächstes aktivieren Sie Gzip für Textformate und bestätigen, dass es funktioniert:

curl -I -H 'Accept-Encoding: gzip' https://example.com/app.js

Sie sollten Content-Encoding: gzip für komprimierbare Antworten und Vary: Accept-Encoding sehen. Wenn Bilder oder ZIP-Dateien als komprimiert angezeigt werden, schränken Sie gzip_types ein; diese Formate sind bereits komprimiert und verschwenden normalerweise CPU.

Danach betrachten Sie die Pufferung. Überprüfen Sie das Fehlerprotokoll auf Meldungen über Upstream-Antworten, die in temporäre Dateien gepuffert werden. Diese Meldungen sind nicht automatisch eine Katastrophe, aber sie sagen Ihnen, dass Nginx Antwortdaten auf die Festplatte schreibt. Wenn dies bei normalen Seitenladevorgängen oder API-Antworten passiert, sind Ihre Proxy-Puffer möglicherweise zu klein für die Arbeitslast. Wenn es nur bei großen Exporten oder Downloads passiert, ist es möglicherweise besser, das Festplatten-Spooling zu akzeptieren, als große Puffer für jeden Anforderungspfad zuzuweisen.

Proxy-Caching sollte zuletzt kommen. Es hat das größte Potenzial und den einfachsten Fehlermodus. Beginnen Sie mit Inhalten, die eindeutig sicher sind: öffentliche Dokumentationsseiten, anonyme Produktkatalogseiten, Bildtransformationsantworten, Paketmetadaten oder API-Antworten, die für jeden Besucher identisch sind. Vermeiden Sie das Caching von allem, das an ein Sitzungscookie, einen Authorization-Header, einen Warenkorb, ein Benutzer-Dashboard, eine Admin-Seite oder eine personalisierte Empfehlung gebunden ist, es sei denn, Ihre Anwendung wurde explizit dafür entwickelt.

Hier ist ein vorsichtigeres Cache-Bypass-Muster als die kurzen Beispiele, die Sie oft sehen:

map $http_authorization $skip_cache_auth {
    default 1;
    ""      0;
}

map $http_cookie $skip_cache_cookie {
    default 0;
    ~*"(session|sid|auth|token)" 1;
}

server {
    location / {
        proxy_pass http://backend_upstream;
        proxy_cache my_cache;
        proxy_cache_valid 200 10m;
        proxy_cache_bypass $skip_cache_auth $skip_cache_cookie;
        proxy_no_cache $skip_cache_auth $skip_cache_cookie;
        add_header X-Cache-Status $upstream_cache_status always;
    }
}

Das muss immer noch zu Ihrer Anwendung passen, aber es macht die wichtige Idee klar: Authentifizierte und sitzungsähnliche Anfragen sollten nicht stillschweigend in einen gemeinsamen Cache gelangen.

Worauf Sie nach der Änderung achten sollten

Beurteilen Sie die Nginx-Optimierung nicht nur anhand eines einzelnen Benchmarks. Beobachten Sie den Server für ein paar normale Traffic-Zyklen. Nützliche Signale sind Festplattenschreibvorgänge unter /var/lib/nginx oder /var/cache/nginx, Upstream-Antwortzeit, Cache-Trefferquote, CPU-Auslastung nach Aktivierung der Komprimierung, 499/502/504-Fehler und Speichernutzung pro Worker. Wenn die CPU nach Gzip ansteigt, sich die Bandbreite aber kaum ändert, senken Sie gzip_comp_level oder schränken Sie die MIME-Typen ein. Wenn die Cache-Trefferquote niedrig ist, wird der Cache möglicherweise durch Cookies, Abfragezeichenfolgen oder Antwort-Header der Anwendung umgangen.

Testen Sie auch das Fehlerverhalten. Stoppen oder verlangsamen Sie den Upstream im Staging und bestätigen Sie, dass proxy_cache_use_stale das tut, was Sie erwarten. Eine veraltete öffentliche Seite während eines kurzen Backend-Ausfalls kann in Ordnung sein. Ein veralteter Kontostand, eine Rechnung oder eine Admin-Seite ist es nicht.

Abschließende Bemerkungen

Gute Nginx-Leistungsarbeit ist meist sorgfältige Hausarbeit. Verwenden Sie Puffer, die groß genug sind, um unnötige Festplatten-I/O zu vermeiden, aber nicht so groß, dass jeder ausgelastete Worker teuer wird. Komprimieren Sie Text, nicht bereits komprimierte Assets. Cachen Sie zuerst öffentliche, wiederholbare Antworten und lassen Sie private Inhalte klar aussteigen. Dann messen Sie weiter, denn die richtige Einstellung für eine kleine PHP-App, eine statische Dokumentationsseite und einen vielbesuchten API-Gateway wird nicht identisch sein.