Web · Performance

HTTP-Caching ohne Mythen: Cache-Control, ETag und Vary richtig einsetzen

Ein Cache ist kein zweiter Speicher, der irgendwann „magisch“ veraltet. HTTP trennt klar zwischen Speichern, frischer Wiederverwendung und Validierung. Wer diese Ebenen versteht, bekommt schnellere Seiten ohne überraschend alte oder falsche Antworten.

Redaktion ByteDepth · 26. September 2026 · 8 Min Lesezeit

Drei Fragen statt eines Cache-Schalters

HTTP-Caching beginnt mit drei getrennten Entscheidungen: Darf eine Antwort gespeichert werden? Wie lange gilt sie als frisch? Und wie wird geprüft, ob eine ältere Kopie noch verwendbar ist? RFC 9111 beschreibt einen Cache als lokalen Antwortspeicher mit Regeln für Ablage, Auswahl und Löschung. Eine frische Antwort kann ohne Kontakt zum Ursprungsserver wiederverwendet werden; eine veraltete Antwort braucht normalerweise eine Validierung.[1]

01 SPEICHERNDarf Browser oder Shared Cache die Antwort ablegen?
02 FRISCHEWie lange darf sie ohne Rückfrage wiederverwendet werden?
03 VALIDIERENKann der Server mit einem Validator eine schlanke Bestätigung liefern?

Diese Trennung erklärt auch einen häufigen Irrtum: no-cache bedeutet nicht „nicht speichern“. Die Direktive verlangt grundsätzlich eine erfolgreiche Validierung vor der Wiederverwendung. Wer die Speicherung unterbinden will, braucht no-store.[1]

Cache-Control steuert die Frische

Mit max-age legt ein Server fest, nach wie vielen Sekunden eine Antwort als veraltet gilt. Für gemeinsam genutzte Caches kann s-maxage eine eigene Frist setzen. private beschränkt die Wiederverwendung auf einen privaten Cache, typischerweise im Browser; public erlaubt die Speicherung in Shared Caches auch in Fällen, in denen sie sonst nicht selbstverständlich wäre.[1]

Cache-Control: public, max-age=300, s-maxage=3600

In diesem Beispiel darf der Browser die Antwort fünf Minuten ohne Rückfrage verwenden. Ein Shared Cache darf sie eine Stunde frisch halten. Das ist kein universelles Rezept: Die passende Frist hängt davon ab, wie schnell eine Ressource tatsächlich geändert wird und welche Folgen eine alte Darstellung hätte.

Für unveränderliche, versionierte Assets ist eine lange Frist sinnvoll. Ein Dateiname wie app.7f3a2c.js ändert sich bei neuem Inhalt; die alte URL kann deshalb lange gecacht werden. Bei HTML-Dokumenten oder APIs ist eine kürzere Frist oder direkte Validierung häufig kontrollierbarer.

ETag spart Inhalt, nicht unbedingt die Anfrage

Ein ETag kennzeichnet eine konkrete Repräsentation. Wird eine gespeicherte Antwort alt, kann der Client den Tag mit If-None-Match zurücksenden. Passt er noch zur aktuellen Repräsentation, antwortet der Server auf GET oder HEAD mit 304 Not Modified statt den Inhalt erneut zu übertragen. RFC 9110 empfiehlt ETags, wenn Änderungen zuverlässig erkannt werden können, weil bedingte Anfragen unnötige Übertragungen reduzieren.[2]

ETag: "page-42" If-None-Match: "page-42" HTTP/1.1 304 Not Modified

Die Netzwerkrunde bleibt dabei bestehen. ETag ist deshalb kein Ersatz für eine sinnvolle Frischezeit: max-age vermeidet während der Frischefrist die Rückfrage, ETag macht die spätere Rückfrage günstiger. Beide Mechanismen ergänzen sich.

Last-Modified und If-Modified-Since erfüllen eine ähnliche Aufgabe mit Zeitstempeln. Entity Tags sind meist präziser, während Zeitangaben als zusätzlicher Validator und für ältere Implementierungen nützlich bleiben.[1]

Vary gehört zur Korrektheit

Eine URL kann abhängig von Request-Headern unterschiedliche Antworten liefern: komprimiert oder unkomprimiert, in verschiedenen Sprachen oder Formaten. Vary teilt dem Cache mit, welche Header zur Auswahl der passenden Variante gehören. Bei Vary: Accept-Encoding darf eine für Brotli erzeugte Antwort nicht einfach an einen Client gehen, der diese Kodierung nicht angekündigt hat.[1]

Vary: Accept-Encoding

Mehr Vary ist jedoch nicht automatisch besser. Jede zusätzliche Dimension kann weitere Cache-Varianten erzeugen und die Trefferquote senken. Besonders Vary: User-Agent führt leicht zu einer kaum beherrschbaren Zahl von Schlüsseln. Die Regel lautet: Nur Header aufnehmen, die die Repräsentation tatsächlich verändern.

Personalisierte Antworten brauchen klare Grenzen

Bei nutzerspezifischen Inhalten ist nicht das Vorhandensein eines Cookies die entscheidende Schutzmaßnahme. RFC 9111 weist ausdrücklich darauf hin, dass Set-Cookie eine Antwort nicht automatisch vom Caching ausschließt. Betreiber müssen das gewünschte Verhalten mit geeigneten Cache-Control-Direktiven festlegen.[1]

Sicherheitsregel: Antworten mit vertraulichen oder benutzerspezifischen Daten sollten nicht versehentlich in gemeinsam genutzten Caches landen. Cache-Schlüssel und Direktiven müssen die tatsächliche Personalisierung abbilden.

Für ein persönliches Dashboard kann Cache-Control: private, no-cache sinnvoll sein: Der Browser darf eine Kopie halten, muss sie aber vor der Wiederverwendung validieren. Für besonders sensible Inhalte kann no-store die passendere Vorgabe sein. Die Wahl sollte bewusst getroffen und mit realen Response-Headern getestet werden.

Eine praktische Strategie

1. Inhalte klassifizieren: unveränderliches Asset, öffentliches Dokument, API-Antwort oder personalisierte Ansicht.
2. Frischezeit festlegen: Wie lange wäre eine alte Antwort fachlich akzeptabel?
3. Validatoren senden: ETag oder Last-Modified für effiziente Revalidierung.
4. Varianten benennen: Vary nur für Header, die den Inhalt wirklich verändern.
5. Shared Caches berücksichtigen: private, public und s-maxage bewusst einsetzen.
6. Verhalten messen: Erstaufruf, Cache-Treffer und bedingte Anfrage getrennt prüfen.

Gutes HTTP-Caching ist damit weniger eine Sammlung aggressiver Performance-Tricks als ein Vertrag über Wiederverwendung. Je klarer Speichern, Frische, Validierung und Varianten beschrieben sind, desto schneller und vorhersehbarer arbeitet die gesamte Auslieferungskette.

Quellen

[1] IETF, RFC 9111 — HTTP Caching.

[2] IETF, RFC 9110 — HTTP Semantics.