Der Header Cache-Control legt fest, ob und wie lange Browser, CDNs und Proxys eine Antwort zwischenspeichern dürfen. Richtig gesetzt, lädt eine Seite wiederkehrenden Besuchern schneller und entlastet den Server; falsch gesetzt, zeigt sie veraltete Inhalte oder lädt jede Datei bei jedem Aufruf neu. Bewährt: Dateien mit Versionsnamen lange cachen, HTML kurz oder mit Revalidierung.
Das Wichtigste in Kürze
max-agegibt die Frische in Sekunden an;no-cacheheißt „vor Nutzung beim Server nachfragen“, nicht „nicht speichern“, das leistetno-store.- Statische Dateien mit Hash oder Version im Namen cachen Sie ein Jahr lang (
max-age=31536000, immutable); HTML bleibt kurz oder revalidiert. - ETag und Last-Modified ermöglichen billige Nachfragen: Der Server antwortet mit
304 Not Modifiedohne Inhalt. - Fehlt
Cache-Control, rät der Browser anhand von Heuristiken, das ist selten, was Sie wollen. - Personalisierte Seiten (Warenkorb, Konto) gehören mit
privateoderno-storemarkiert, sonst droht Auslieferung fremder Inhalte durch Shared Caches.
Was macht Cache-Control und warum ist es relevant?
Jede Datei, die ein Besucher lädt, durchläuft potenziell mehrere Zwischenspeicher: den Browser-Cache, einen Proxy des Unternehmens, ein CDN. Der Header Cache-Control ist die Anweisung des Servers, wie diese Speicher mit der Antwort umgehen sollen. Der Standard dazu ist RFC 9111 (HTTP Caching); eine gut lesbare Einführung bietet MDN (beides in den Quellen).
Warum lohnt sich ein genauer Blick? Aus drei Gründen. Erstens Geschwindigkeit: Eine Datei aus dem Cache kostet keine Netzwerkanfrage, Wiederholungsbesucher sehen die Seite spürbar schneller; das beeinflusst auch Messgrößen wie die Core Web Vitals (siehe web.dev in den Quellen) und die gefühlte Antwortzeit. Zweitens Serverlast: Jede aus dem Cache bediente Anfrage erreicht den Server nicht. Drittens Korrektheit: Zu lange gespeicherte Inhalte zeigen nach einem Update die alte Version, und fehlerhaft gecachte, personalisierte Seiten können Datenschutzprobleme auslösen.
Welche Direktiven gibt es und was bedeuten sie?
| Direktive | Bedeutung | Typischer Einsatz |
|---|---|---|
max-age=N | Antwort gilt N Sekunden als frisch; in dieser Zeit ohne Rückfrage nutzbar | Statische Dateien, kurz gecachtes HTML |
s-maxage=N | Wie max-age, aber nur für Shared Caches (CDN, Proxy); hat dort Vorrang | CDN länger cachen lassen als den Browser |
no-cache | Darf gespeichert werden, muss aber vor jeder Nutzung beim Server revalidiert werden | HTML, das immer aktuell sein soll, aber 304-fähig bleibt |
no-store | Nicht speichern, nirgendwo | Sensible Inhalte (Solo, Zahlungsdaten) |
public | Auch Shared Caches dürfen speichern, selbst wenn es sonst nicht der Fall wäre (z. B. bei Autorisierung) | Selten nötig, bei CDN-Assets |
private | Nur der Browser des Nutzers darf speichern, keine Shared Caches | Personalisierte Seiten |
immutable | Inhalt ändert sich während der Frische nie; Browser fragen auch beim Neuladen nicht nach | Dateien mit Hash im Namen |
must-revalidate | Nach Ablauf der Frische nicht ohne Rückfrage nutzen, auch nicht bei Serverfehler | Wenn veraltete Inhalte inakzeptabel sind |
stale-while-revalidate=N | Abgelaufene Antwort darf N Sekunden weiter ausgeliefert werden, während im Hintergrund neu geladen wird | Schnell wirkende Seiten mit leichter Unschärfe |
stale-if-error=N | Bei Fehlern des Ursprungsservers darf eine alte Antwort N Sekunden ausgeliefert werden | Robustheit bei Ausfällen |
Die letzten beiden sind in RFC 5861 beschrieben und werden nicht von jedem Cache unterstützt; testen Sie sie in Ihrer Umgebung. immutable stammt aus RFC 8246. Direktiven lassen sich kombinieren, etwa public, max-age=600, stale-while-revalidate=60.
Zwei Missverständnisse halten sich hartnäckig. no-cache verhindert nicht das Speichern, sondern erzwingt Rückfragen; wer wirklich nichts speichern lassen will, braucht no-store. Und das veraltete Pragma: no-cache stammt aus HTTP/1.0 und ist als Antwort-Header nicht zuverlässig definiert; ein modernes Cache-Control macht es überflüssig. Der ältere Header Expires (ein absolutes Datum) wird ignoriert, sobald max-age vorhanden ist.
Wie funktioniert die Revalidierung mit ETag und Last-Modified?
Ist eine Antwort nicht mehr frisch, muss der Cache nicht alles neu laden, sondern kann fragen, ob sich etwas geändert hat. Dafür liefert der Server Validatoren mit:
ETag: "a1b2c3": eine Kennung der Version der Datei.Last-Modified: Wed, 14 Oct 2026 08:30:00 GMT: der Zeitpunkt der letzten Änderung.
Bei der nächsten Anfrage sendet der Browser If-None-Match: "a1b2c3" beziehungsweise If-Modified-Since mit. Ist die Datei unverändert, antwortet der Server mit 304 Not Modified und ohne Inhalt; der Browser nutzt seine Kopie. Das spart Bandbreite, kostet aber weiterhin eine Anfrage (Statuscodes erklärt dieser Ratgeber). Deshalb ist max-age mit längerer Frist für unveränderliche Dateien besser als reine Revalidierung.
Ohne Cache-Control bleibt es dem Cache überlassen, wie lange er Antworten frisch hält. RFC 9111 erlaubt in diesem Fall eine heuristische Frische, die häufig als Bruchteil (oft 10 %) der Zeit seit Last-Modified berechnet wird. Eine Datei, die vor 100 Tagen zuletzt geändert wurde, könnte so rund 10 Tage lang ohne Rückfrage ausgeliefert werden. Wer das nicht will, setzt Cache-Control ausdrücklich.
Welche Cache-Strategie passt zu welchem Inhalt?
| Inhalt | Empfohlene Einstellung | Begründung |
|---|---|---|
CSS/JS/Schriften mit Hash oder Version im Dateinamen (app.3f9a1c.js) | public, max-age=31536000, immutable | Neue Version = neuer Name, alte Datei ändert sich nie |
| Bilder, die selten wechseln, mit festem Namen | public, max-age=2592000 (30 Tage) oder kürzer | Austausch ohne Namenswechsel braucht kürzere Frist |
| HTML-Seiten (Artikel, Landingpages) | no-cache oder max-age=60..600 mit ETag | Inhalte ändern sich, Links auf Assets müssen aktuell sein |
| Startseite eines aktiven Shops oder Magazins | Kurz (z. B. max-age=60) plus stale-while-revalidate | Balance aus Last und Aktualität |
| Personalisierte Seiten (Solo, Warenkorb, Checkout) | private, no-store | Keine Speicherung in Shared Caches, keine Rückgabe über „Zurück“ |
| API-Antworten | Je nach Daten no-store oder max-age kurz mit ETag | Aktualität bestimmt, nicht Gewohnheit |
| Weiterleitungen (301) | Bewusst setzen, siehe Weiterleitungen und Redirect-Ketten | Dauerhafte Weiterleitungen werden von Browsern hartnäckig gespeichert |
Angenommen (Beispielannahme), Ihre Seite lädt pro Aufruf 1,8 MB an statischen Dateien (Skripte, Styles, Bilder, Schriften), und Sie haben 20.000 Aufrufe am Tag, davon 40 % von Wiederholungsbesuchern. Ohne Caching-Header oder mit no-cache laden diese Besucher alle Dateien jedes Mal neu oder revalidieren sie: Bei Revalidierung fallen zwar nur kleine 304-Antworten an, aber pro Datei eine Anfrage. Mit max-age=31536000, immutable für Dateien mit Hash entfällt auch das. Rechnung für die Datenmenge, wenn nichts gecacht wird: 20.000 × 1,8 MB = 36 GB pro Tag. Cachen die 8.000 Wiederholungsbesucher 90 % davon, sparen Sie 8.000 × 1,8 MB × 0,9 = 12,96 GB pro Tag, also rund 36 %. Die Zahlen sind eine Rechenillustration; Ihre Werte entnehmen Sie Ihrem Server-Log oder CDN.
Wie vermeiden Sie veraltete Dateien: Fingerprinting
Je länger Sie eine Datei cachen, desto wichtiger ist ein Weg, sie bei Änderungen zu ersetzen. Das Ziel ist, dass sich bei jeder Änderung der Dateiname ändert, damit der Browser sie als neue Ressource behandelt. Das geschieht durch einen Hash im Namen (app.3f9a1c.css) oder durch einen Versionsparameter (app.css?v=20261016). Moderne Build-Werkzeuge erzeugen Hash-Namen automatisch; bei Eigenbau genügt ein Parameter, der sich bei jedem Deployment ändert, etwa die Datei-Änderungszeit.
Wichtig ist, dass die HTML-Seite, die auf die Dateien verweist, nicht lange gecacht wird: Sie ist die Einstiegstür. Ist die Startseite einen Tag lang im Browser gespeichert, verweist sie einen Tag lang auf alte Dateinamen, die vielleicht nicht mehr existieren. Deshalb gilt die Faustregel: HTML kurz oder revalidieren, Assets mit Versionsnamen lang.
Wie setzen Sie Cache-Control in nginx und Apache?
nginx
# Statische Dateien mit Versionsname: ein Jahr, unveränderlich
location ~* \.(?:css|js|woff2|svg|webp|jpg|png)$ {
add_header Cache-Control "public, max-age=31536000, immutable" always;
# Achtung: add_header hier ersetzt geerbte Header des server-Blocks,
# Security-Header ggf. wiederholen (siehe Ratgeber Security-Header).
}
# HTML: immer revalidieren
location / {
add_header Cache-Control "no-cache" always;
try_files $uri $uri/ /index.php?$args;
}
Alternativ erzeugt die Direktive expires 1y; sowohl Expires als auch Cache-Control: max-age=31536000. Beachten Sie, dass add_header keinen bestehenden Cache-Control-Header ersetzt, den PHP oder ein Proxy bereits gesetzt hat; es kann zu doppelten Headern kommen. Bei PHP-Anwendungen steuert oft die Anwendung selbst die Header (WordPress-Cache-Plugins, Shop-Systeme); setzen Sie dann nicht zusätzlich Regeln im Server, die dagegen arbeiten.
Apache
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType image/webp "access plus 1 month"
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(css|js|woff2)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
<FilesMatch "\.html$">
Header set Cache-Control "no-cache"
</FilesMatch>
</IfModule>
PHP (dynamische Seiten)
// Persönliche Seite: nicht in Shared Caches, nicht speichern
header('Cache-Control: private, no-store');
// Öffentliche Seite: 5 Minuten, danach im Hintergrund aktualisieren
header('Cache-Control: public, max-age=300, stale-while-revalidate=60');
PHP-Sitzungen setzen bei aktivem session_start() eigene Cache-Header (Voreinstellung session.cache_limiter = nocache); das verhindert Caching, auch wenn Sie es für öffentliche Seiten wünschen. Setzen Sie session_cache_limiter('') oder nutzen Sie Sitzungen nur dort, wo sie nötig sind.
Wie prüfen Sie Cache-Header mit curl?
# Header einer Datei ansehen
curl -sI https://www.example.de/assets/app.3f9a1c.css
# Interessante Zeilen herausfiltern
curl -sI https://www.example.de/ | grep -iE 'cache-control|etag|last-modified|expires|age|vary|set-cookie'
# Revalidierung testen: ETag aus der ersten Antwort mitsenden
curl -sI -H 'If-None-Match: "a1b2c3"' https://www.example.de/assets/app.css
Bei der letzten Abfrage sollte HTTP/1.1 304 Not Modified kommen, wenn der ETag noch passt. Weitere Hinweise liefert der Header Age: Er zeigt, wie viele Sekunden eine Antwort bereits in einem Shared Cache (CDN) liegt. Die Header X-Cache oder CF-Cache-Status variieren je nach Anbieter und zeigen, ob ein Treffer vorlag. Prüfen Sie auch im Browser: In den Entwicklertools (Netzwerk) steht bei zwischengespeicherten Antworten „aus Memory/Disk-Cache“; Sie sollten dort nicht mit deaktiviertem Cache testen, sonst sehen Sie das Wiederholungsverhalten nicht.
Achten Sie auf Vary: Der Header teilt Caches mit, nach welchen Anfrage-Headern sich die Antwort unterscheidet. Vary: Accept-Encoding ist normal (komprimiert oder unkomprimiert). Vary: Cookie oder Vary: User-Agent machen CDN-Caching sehr ineffizient, weil für jede Kombination eine eigene Kopie entsteht.
Welche typischen Fehler passieren?
| Fehler | Folge | Gegenmaßnahme |
|---|---|---|
Lange max-age für Dateien ohne Versionsnamen | Besucher sehen nach Updates altes CSS/JS, bis die Frist abläuft | Hash/Version im Dateinamen, oder kürzere Frist |
| Lange Frist für HTML | Neue Inhalte erscheinen verspätet, Links auf alte Assets | no-cache oder kurze Frist |
no-cache mit „nicht speichern“ verwechselt | Sensible Inhalte bleiben gespeichert | no-store für wirklich vertrauliche Inhalte |
Personalisierte Seiten ohne private in CDN | Auslieferung fremder Inhalte an andere Nutzer | private, no-store; CDN-Regeln prüfen |
Kein Cache-Control überhaupt | Heuristiken entscheiden, unvorhersehbares Verhalten | Header ausdrücklich setzen |
Set-Cookie auf statischen Dateien | CDNs und Proxys cachen die Antwort nicht oder nur eingeschränkt | Cookies auf statischen Pfaden vermeiden |
| Doppelte oder widersprüchliche Header (Anwendung, Server, CDN) | Unklarer effektiver Wert | An einer Stelle setzen; Ergebnis mit curl prüfen |
| Fehlerseiten werden gecacht | Kurzer 500er wird lange ausgeliefert | Fehlerantworten ohne lange Frist; no-store bei 5xx |
Mit immutable auf Dateien mit festem Namen | Ein Fehler kann ein Jahr im Browser stecken | Nur mit Fingerprinting einsetzen |
Ein besonders tückischer Fall: Ein Wartungs- oder Fehlerhinweis, der mit Status 200 und langer Frist ausgeliefert wird, bleibt in Browsern und CDNs liegen, obwohl die Seite längst wieder läuft. Das erklärt manche Meldungen wie „bei mir geht es noch nicht“ nach einer Störung (siehe Ausfallursachen von Websites) und ist ein Grund, Wartungsseiten mit Status 503 und ohne Caching auszuliefern.
Checkliste: Caching prüfen
- Haben alle statischen Dateien einen
Cache-Control-Header mit sinnvoller Frist? - Haben veränderliche Dateien einen Hash oder eine Version im Namen, bevor Sie
immutablesetzen? - Ist HTML mit
no-cacheoder kurzer Frist ausgeliefert und mit ETag oder Last-Modified versehen? - Sind personalisierte Bereiche (Solo, Warenkorb, Checkout) mit
private, no-storemarkiert? - Kommt bei der Revalidierung mit
If-None-Matchein304? - Sind Header nur an einer Stelle gesetzt oder bewusst abgestimmt (Anwendung, Server, CDN)?
- Haben Wartungs- und Fehlerseiten keinen langen Cache-Wert?
- Nach einem Deployment: CDN-Cache bei Bedarf leeren und prüfen, ob die neuen Dateinamen ankommen.
Grenzen und Einordnung
Caching ist eine Optimierung, kein Reparaturmittel: Eine langsame Anwendung wird durch Header nicht schneller, sondern nur seltener belastet. Und das Verhalten hängt von jedem Glied der Kette ab. Browser unterscheiden sich im Detail, manche CDNs ignorieren Direktiven oder überschreiben sie nach eigenen Regeln, und Cache-Plugins können Ihre Einstellungen ersetzen. Eine Prüfung von außen zeigt, welche Header ankommen, aber nicht, wie jeder einzelne Browser oder jedes CDN damit umgeht. Fehler in der Cache-Steuerung sind zudem selten ein Ausfall im Sinne eines Monitors: Die Seite antwortet mit 200, nur eben mit veraltetem Inhalt. Sie erkennen sie deshalb am ehesten durch gezielte Prüfungen, etwa einen Keyword-Monitor auf einen erwarteten Inhalt, nicht durch reine Verfügbarkeitsprüfung.
Wie setzen Sie das mit UPTIMESHIELD um?
Der Sofort-Report fragt die Cache-Steuerung Ihrer Seite ab und führt sie als Teil der Technik-Bewertung samt Hinweisen in der Maßnahmenliste auf. Das Verfahren zur Messung ist in der Messmethodik beschrieben. Wiederkehrende Kontrollen übernehmen die Website-Checks im Dashboard, die Notenverlauf und Veränderungen („neu“ oder „behoben“) festhalten, etwa wenn nach einem Relaunch plötzlich Cache-Header fehlen (siehe Relaunch und Umzug überwachen). Ob der Inhalt tatsächlich aktuell ist, prüft ein Keyword-Monitor auf einen erwarteten Text. Die Funktionen setzen ein kostenloses Solo-Konto voraus (Registrierung).
Quellen und weiterführende Standards
Externe Links führen zu den Original-Spezifikationen und offiziellen Dokumentationen. Die Einordnung und die Beispielrechnungen stammen aus der Messmethodik von UPTIMESHIELD.
Selbst prüfen: Testen Sie jetzt, ob Ihre Website erreichbar ist und wie schnell sie antwortet – mit dem Uptime Checker.