Caching ist der stärkste Performance-Multiplikator moderner Software. Trotzdem behandeln die meisten Teams es als Nachgedanken — sie stapeln Schichten übereinander, ohne deren Zusammenspiel zu verstehen, verschenken Leistung und handeln sich subtile Fehler ein, etwa veraltete Daten und inkonsistente Caches.
Eine einzelne Cache-Schicht kann nicht jedes Problem lösen. Browser-Caches, CDN-Edges, Object Stores und Opcode-Caches existieren, weil unterschiedliche Abschnitte des Anfragezyklus unterschiedliche Engpässe haben. Zu verstehen, wie diese Schichten zusammenspielen und wann welche invalidiert werden muss, unterscheidet Systeme mit Antwortzeiten unter 100 ms von jenen, die Nutzer frustrieren.
Dieser Leitfaden behandelt die Caching-Architektur über den gesamten Stack, die E-Commerce-Flotten im großen Maßstab trägt: wie Sie Caches schichten, die Invalidierung über Schichten hinweg abstimmen und die Fallen vermeiden, in die die meisten Teams tappen.
Die fünf Cache-Schichten
Eine robuste Caching-Architektur reicht vom Browser des Nutzers bis in den Arbeitsspeicher des Anwendungsservers. Jede Schicht deckt einen anderen Engpass ab und bedient ein anderes Publikum.
1. Browser-Cache: der Speicher des Clients
Lädt der Browser eine Seite, legt er statische Ressourcen — Bilder, Stylesheets, Skripte, Schriften — lokal auf der Festplatte oder im Arbeitsspeicher ab. Über HTTP-Header wie Cache-Control, Expires und ETag entscheidet er, ob sie noch frisch sind.
Laut dem offiziellen HTTP-Caching-Leitfaden von web.dev ist der Cache-Control-Header „der primäre Mechanismus zur Steuerung des Caching-Verhaltens“ über alle Schichten hinweg. Ruft ein Nutzer dieselbe Seite erneut auf, prüft der Browser zuerst seinen lokalen Cache. Ist die Ressource noch frisch, stellt der Browser null Netzwerkanfragen. Allein das eliminiert den größten Teil des Datenverkehrs und verbessert die wahrgenommene Geschwindigkeit deutlich.
Best Practice: Verwenden Sie versionierte URLs (mit Fingerprint) für unveränderliche Assets. web.dev rät: „Wenn Sie Anfragen für URLs beantworten, die Fingerprint- oder Versionsinformationen enthalten und deren Inhalt sich nie ändern soll, setzen Sie Cache-Control: max-age=31536000.“ Build-Werkzeuge wie webpack automatisieren das, indem sie Inhalts-Hashes in Dateinamen einbetten (z. B. style.x234dff.css). Inhaltsänderungen erzeugen automatisch neue URLs und erzwingen frische Downloads, ohne den Cache zu verschmutzen.
2. CDN-/Edge-Cache: Inhalte am Netzwerkrand
CDN-Server (Cloudflare, Akamai, AWS CloudFront) sitzen zwischen Nutzern und Ihrem Ursprungsserver. Fragt eine Besucherin in London Inhalte an, die ursprünglich aus New York ausgeliefert werden, liefert ein CDN sie aus einem Londoner Edge-Knoten, sofern zwischengespeichert — die Umlaufzeit sinkt von über 100 ms auf unter 50 ms.
CDNs cachen statische wie dynamische Inhalte, das Verhalten unterscheidet sich jedoch. Der HTTP-Caching-Leitfaden von Jono Alderson hält fest: „Cloudflare cacht HTML standardmäßig nicht — das erfordert ausdrückliche Konfiguration.“ Das ist Absicht: HTML ändert sich häufig und enthält oft personalisierte Daten. Wer HTML unbedacht am Edge cacht, produziert Albträume mit veralteten Daten.
Steuern Sie das Edge-Caching über die Direktive s-maxage im Cache-Control-Header, die max-age speziell für gemeinsame Caches wie CDNs überschreibt:
s-maxage=3600: 1 Stunde am Edge zwischenspeicherns-maxage=0: nie am Edge cachen, immer neu validierenprivate: nie am Edge cachen, nur im Browser
Für WooCommerce und E-Commerce erfordert Edge-Caching chirurgische Präzision. Die Best Practices für WooCommerce und Cloudflare warnen ausdrücklich: Nehmen Sie /cart, /checkout und /my-account vom Edge-Caching aus. Werden diese Seiten gecacht, sehen Kunden veraltete Warenkörbe, und personalisierte Daten geraten nach außen. Nutzen Sie Cloudflare Page Rules, um das Caching auf diesen URLs zu umgehen.
3. Full-Page-Cache: fertiges HTML am Server
Full-Page-Caching (etwa WP Rocket, LiteSpeed Cache, Varnish) legt gerendertes HTML auf Serverebene ab und liefert jedem Besucher exakt dasselbe HTML aus, bis die TTL abläuft. Das funktioniert für statische Landingpages und öffentliche Inhalte, scheitert aber bei personalisierten oder dynamischen Seiten.
Zentrale Einschränkung: Cachen Sie niemals Seiten mit nutzerspezifischen Daten, Sitzungstoken oder Formularübermittlungen. Ein Full-Page-Cache, der versehentlich die Kontoseite eines Nutzers an einen anderen ausliefert, ist ein Sicherheitsvorfall und ein Datenleck.
Legitime Einsatzfälle: Produktlisten, Blogbeiträge, Marketingseiten, Kategorieseiten, FAQs. Die meisten Shops cachen diese je nach Aktualisierungsfrequenz 1 bis 24 Stunden.
4. Redis-/Object-Cache: Abfrageergebnisse im Arbeitsspeicher
Die Datenbank ist oft das langsamste Glied. Redis (oder Memcached) hält teure Rechenergebnisse, häufig abgefragte Datenstrukturen und ORM-Ergebnisse im Arbeitsspeicher und erspart wiederholte Datenbankzugriffe.
Redis speichert alle Daten im Arbeitsspeicher und erreicht Latenzen im Mikrosekundenbereich statt Millisekunden wie bei Datenbankabfragen. Der Leitfaden von Kinsta zu Redis für WordPress dokumentiert Praxiswerte: „Eine frische WordPress-Installation zeigte fast 50 % kürzere Ladezeiten“ mit aktiviertem Redis-Object-Cache.
Wann Redis am meisten bringt:
- Lastspitzen: Redis puffert den Ansturm und liefert zwischengespeicherte Daten, während die Datenbank durchatmet
- Teure Abfragen: Ergebnisse aufwendiger Joins oder Aggregationen (Top-10-Produkte, Kategoriesummen)
- Wiederholte Lesezugriffe: Sitzungsdaten, Nutzereinstellungen, Beitragszahlen, Term-Meta
Redis ist kein Allheilmittel. Der Redis-Realitätscheck von WebHostMost warnt: „Wenn Ihre wp_options-Autoload-Daten über 2 MB groß sind, cacht Redis Ballast.“ Prüfen Sie zuerst Ihre Datenbank. Entfernen Sie tote Daten aus wp_options, wp_postmeta und den Action-Scheduler-Tabellen, bevor Sie Redis ergänzen. Eine Trefferquote unter 80 % zeigt, dass Redis nicht hilft.
5. OPcache: der Opcode-Cache in der PHP-Engine
OPcache (Zend OPcache, ab PHP 5.5 enthalten) übersetzt PHP-Quellcode einmal in Bytecode und hält diesen im gemeinsamen Speicher. Ohne OPcache kompiliert PHP jede Datei bei jeder Anfrage neu. Mit OPcache passiert das einmal je Deployment.
Leistungsgewinn: bis zu 70 % weniger CPU-Last auf stark frequentierten Seiten. Das ist der einfachste Gewinn, und die meisten Hoster aktivieren es standardmäßig. Prüfen mit phpinfo() oder php -m | grep opcache.
Konfiguration:
opcache.enable=1: OPcache aktivierenopcache.memory_consumption=256: Speicherpool in MB (bei großen Codebasen erhöhen)opcache.max_accelerated_files=10000: Anzahl zwischengespeicherter Dateienopcache.validate_timestamps=0(Produktion): Dateiänderungen nicht prüfen, Neuladen über das Deployment
Vilee LLC verbindet tiefe technische Expertise in WordPress-/WooCommerce-Entwicklung mit KI-gestützter Automatisierung und betreibt damit über 520 profitable Onlinegeschäfte im großen Maßstab.
Wie die Schichten zusammenspielen: der Anfrageweg
Die Reihenfolge, in der Caches geprüft werden, ist entscheidend für korrektes Verhalten:
| Stufe | System | Latenz | Bei Treffer |
|---|---|---|---|
| Browser | lokale Platte / Speicher | < 5 ms | gecachte Datei nutzen, keine Netzwerkanfrage |
| Netzwerk | ISP-Cache des Nutzers (optional) | 10–50 ms | nutzt ggf. Cache, abhängig vom ISP |
| CDN-Edge | Cloudflare / AWS / Akamai | 20–100 ms | gecachte Antwort vom Edge liefern |
| Full-Page-Cache | Varnish / WP Rocket / LiteSpeed | 5–20 ms | gerendertes HTML ohne PHP liefern |
| Object-Cache | Redis / Memcached | < 1 ms | vorberechnete Daten ohne DB-Abfrage liefern |
| OPcache | gemeinsamer PHP-Speicher | Mikrosekunden | kompilierten Bytecode ohne Parsen liefern |
| Datenbank | MySQL / PostgreSQL | 5–50 ms | Abfrage ausführen (langsamster Weg) |
Eine gut entworfene Anfrage trifft meist drei Caches: Browser → Edge → Redis → keine Datenbankabfrage. Ein Fehlschlag auf jeder Schicht fällt bis zur Datenbank durch, dem teuersten Weg.
Cache-Invalidierung: das harte Problem
Cache-Invalidierung ist notorisch schwierig. Der Witz in der Branche lautet: „Es gibt nur zwei schwere Probleme in der Informatik: Cache-Invalidierung und Benennungen.“ Ganz falsch ist das nicht.
Das Problem: Ändern sich Daten, werden alle Caches, die sie halten, veraltet. Sie müssen die Schichten in der richtigen Reihenfolge invalidieren, sonst entstehen Zeitfenster, in denen verschiedene Nutzer verschiedene Wahrheiten sehen.
Invalidierungsstrategien
Der Leitfaden von Codelit zu Invalidierungsstrategien nennt drei Grundansätze:
1. Nach Ablaufzeit (TTL)
Jeder Eintrag erhält eine Ablaufzeit. Läuft sie ab, verwirft der Cache den Eintrag automatisch. Am einfachsten, aber am wenigsten präzise:
- Vorteile: keine Abstimmung nötig, automatische Bereinigung
- Nachteile: veraltete Daten für bis zu einer TTL-Dauer; zu langes Cachen verschwendet Ressourcen
Gut für: Produktpreise, Bestandszahlen, Social-Media-Feeds (wo leichte Verzögerung akzeptabel ist)
2. Ereignisgesteuerte Invalidierung
Ändern sich Daten (Produkt aktualisiert, Bestellung aufgegeben, Kommentar veröffentlicht), werden die betroffenen Einträge sofort verworfen. Das erfordert Abstimmung zwischen Anwendung und Cache-Schichten.
Beispiel: Wird Produkt 42 aktualisiert:
- Datenbank aktualisieren
product:42:*aus Redis entfernen (Mustererkennung)- Über die CDN-API
/product/42/am Edge löschen - Optional den Full-Page-Cache betroffener Kategorien leeren
Vorteile: Daten sind unmittelbar nach der Änderung frisch
Nachteile: komplexe Orchestrierung; Fehlerfälle müssen behandelt werden (etwa Zeitüberschreitung der CDN-API)
3. Tag-basierte Invalidierung
Einträge werden nach semantischen Tags gruppiert. Ändern sich Daten, werden alle Einträge mit passendem Tag verworfen — granularer als das Löschen nach URL:
- Antworten taggen:
product:42, category:electronics, sale:summer2026 - Produkt aktualisieren: Tags
product:42undcategory:electronicsleeren - Sommeraktion starten: Tag
sale:summer2026leeren (invalidiert alle Aktionsbanner auf einmal)
Cloudflares Cache Rules für WordPress/WooCommerce unterstützen tag-basiertes Löschen per API und erlauben so präzise Invalidierung, ohne das Purge-Kontingent zu verschwenden.
Reihenfolge beim Leeren: das Thundering-Herd-Problem
Läuft ein beliebter Cache-Eintrag ab, können viele Anfragen gleichzeitig auf die Datenbank treffen. Diese „donnernde Herde“ erzeugt eine Lastspitze und kann Datenbank oder Ursprungsserver umwerfen.
Lösung: Schutz vor Cache-Stampedes:
- Stale-While-Revalidate: veralteten Inhalt ausliefern und im Hintergrund neu laden. web.dev dokumentiert:
Cache-Control: stale-while-revalidate=86400erlaubt, gecachte Inhalte bis zu einen Tag nach Ablauf auszuliefern, während im Hintergrund revalidiert wird. - Verteilte Sperre: nur ein Worker erneuert den Cache, die übrigen warten oder nutzen den alten Wert
- Gestaffelte TTLs: nicht alle Einträge gleichzeitig ablaufen lassen; TTLs um 10–20 % variieren, damit sich Erneuerungen verteilen
TTL-Strategie und Abstimmung über Schichten hinweg
Verschiedene Caches brauchen verschiedene TTLs, je nach Änderungshäufigkeit und Konsistenzanforderung:
| Inhaltstyp | Browser-Cache | CDN-TTL | Redis-TTL | Begründung |
|---|---|---|---|---|
| statisches JS/CSS | 1 Jahr | 1 Jahr | entfällt | versionierte URLs, unveränderlich |
| Produkt-HTML | 1 Stunde | 6 Stunden | 24 Stunden | Produktdaten ändern sich; Edge lässt sich langsamer leeren |
| Kategorieliste | 30 Minuten | 4 Stunden | 12 Stunden | Bestände schwanken; Nutzer erwarten aktuelle Verfügbarkeit |
| Nutzersitzung | entfällt | kein Caching | 30 Minuten | personenbezogen, nie am Edge cachen |
| Warenkorb | entfällt | kein Caching | läuft mit der Sitzung ab | Echtzeit-Aktualisierung, darf nicht veralten |
Grundregel: Die Edge-TTL sollte immer größer oder gleich der Browser-TTL sein. Ist die Browser-TTL länger als die Edge-TTL, liefert der Browser veraltete Inhalte, während der Edge frische hat — das stiftet Verwirrung und Fehler.
Veraltete Daten und personalisierte Datenlecks vermeiden
Caching bringt zwei kritische Risiken für Sicherheit und Korrektheit mit sich:
Veraltete Daten
Eine gecachte Antwort ist älter als die zugrunde liegenden Daten. Beispiele:
- Preis ändert sich, Cache wird nicht invalidiert → Kundin sieht den alten Preis
- Bestand erschöpft, Full-Page-Cache nicht geleert → Überverkauf
- Kommentar gelöscht, Edge-Cache besteht fort → Geisterantworten bleiben sichtbar
Vorbeugung: Invalidierung so entwerfen, dass sie vor oder unmittelbar nach der Datenänderung auslöst. Für kritische Daten ereignisgesteuert invalidieren, nur für unkritische rein per TTL.
Lecks personalisierter Daten
Gecachte Inhalte mit personenbezogenen Daten eines Nutzers werden an einen anderen ausgeliefert. Beispiele:
- Kontoseite wird gecacht und an einen nicht angemeldeten Besucher ausgeliefert
- Warenkorbinhalt wird gecacht → einem anderen Nutzer angezeigt
- Dashboard mit Bestellhistorie wird gecacht → für Angreifer sichtbar
Vorbeugung:
- authentifizierte Antworten nie am Edge oder als Full-Page cachen
Cache-Control: privatefür nutzerspezifische Inhalte verwenden (nur Browser)Vary: Cookienutzen, um den Cache nach Sitzung zu trennen (Vorsicht: erzeugt sehr viele Einträge)- Caching für
/my-account,/checkout,/dashboardund Ähnliches ausdrücklich umgehen
Wie die Best Practices zu WooCommerce und Cloudflare festhalten: „Eine saubere Konfiguration erlaubt Shops, die Vorteile von Cloudflare zu nutzen, ohne die dynamischen Funktionen zu stören, auf die WooCommerce angewiesen ist.“
Entwurf für E-Commerce-Flotten im großen Maßstab
Wer Hunderte oder Tausende Shops betreibt, braucht Caching, das zugleich autonom und abgestimmt arbeitet.
Mandantentrennung
Der Cache einer Website darf andere nicht verunreinigen. Strategien:
- Getrennte Redis-Datenbanken: jeder Mandant nutzt eine eigene Redis-DB (0–15)
- Schlüsselpräfixe:
tenant:42:product:1001verhindert Kollisionen - Gemeinsamer Redis-Cluster mit Namensräumen: ein Cluster bedient alle, die Anwendungen präfixen ihre Schlüssel
Automatisierte Invalidierung
Manuelles Leeren skaliert nicht. Setzen Sie um:
- Datenbank-Trigger → Warteschlange für Invalidierung
- Nachrichtenbus (Redis Streams, Kafka) → Worker, die CDN- und Full-Page-Caches leeren
- API-Hooks → Reaktion auf Produktänderungen, Bestellungen und Ähnliches
Monitoring und Kennzahlen
Blindes Caching ist gefährlich. Verfolgen Sie:
- Trefferquoten: über 80 % ist gesund
- Vorfälle mit veralteten Daten: wie oft lieferte der Cache Überholtes aus?
- Spitzen bei Fehlschlägen: ein plötzlicher Anstieg deutet auf Invalidierung oder Serverausfall hin
- Speicherauslastung: Eviction-Rate von Redis (sollte unter 5 % liegen)
Caching-Checkliste für E-Commerce-Teams
- OPcache in PHP aktivieren, mit
php -m | grep opcacheprüfen - Browser-Cache mit versionierten URLs für statische Assets konfigurieren (
max-age=31536000) - CDN einrichten (Cloudflare oder vergleichbar), HTML-Caching nur für öffentliche Seiten aktivieren
- dynamische Seiten vom Edge-Cache ausnehmen:
/cart,/checkout,/my-account,/dashboard - Redis-Object-Cache ausrollen, Trefferquote überwachen (über 80 %)
- Datenbank vor dem Caching auf tote Daten prüfen,
wp_optionsundwp_postmetabereinigen - ereignisgesteuerte Invalidierung für kritische Daten umsetzen (Preise, Bestände)
- tag-basiertes Löschen am CDN nutzen, um Kontingent zu sparen
- Stale-While-Revalidate für Robustheit setzen:
Cache-Control: stale-while-revalidate=86400 - Cache-Verhalten mit echten Daten testen, Nutzerwege simulieren (in den Warenkorb legen, Checkout, Kontozugriff)
- Trefferquote, Eviction-Rate und Vorfälle mit veralteten Daten überwachen, bei Auffälligkeiten alarmieren
- den Ablauf der Invalidierung für Ihr Team dokumentieren und zum Runbook machen
Kurz gefragt
Frage: Sollten wir mit Redis oder mit Full-Page-Cache arbeiten?
Antwort: Mit beidem. Redis cacht Datenbankabfragen und teure Berechnungen. Der Full-Page-Cache (WP Rocket, LiteSpeed) cacht gerendertes HTML für öffentliche Seiten. Sie erfüllen verschiedene Zwecke und ergänzen sich. Full-Page ist schneller (PHP entfällt), aber unflexibler (keine Personalisierung). Nutzen Sie Full-Page für statische Landingpages und Redis für personalisierte Inhalte wie Produktempfehlungen.
Frage: Was passiert, wenn eine Cache-Schicht ausfällt (Redis weg, CDN nicht erreichbar)?
Antwort: Entwerfen Sie für sanften Rückfall. Ist Redis ausgefallen, greifen Sie auf Datenbankabfragen zurück (langsamer, aber korrekt). Ist das CDN nicht erreichbar, liefern Sie vom Ursprung aus (langsam, aber verfügbar). Nutzen Sie Health Checks und Circuit Breaker. Für Robustheit setzen Sie Cache-Control: stale-if-error=604800, um bei Ausfall des Ursprungs veraltete Inhalte auszuliefern.
Frage: Wie vermeiden wir die donnernde Herde, wenn ein beliebter Eintrag abläuft?
Antwort: Mit Stale-While-Revalidate (veraltet ausliefern, im Hintergrund erneuern), verteilten Sperren (nur ein Worker erneuert) oder gestaffelten TTLs (um 10–20 % variieren). Die Optimierungsstrategien von Redis empfehlen proaktives Erneuern: Einträge regelmäßig vor ihrem Ablauf auffrischen, statt auf den Ablauf zu warten.
Frage: Gibt es eine universelle TTL für alle Inhalte?
Antwort: Nein. Statische Assets bekommen lange TTLs (ein Jahr und mehr), weil ihre URLs versioniert sind. Produktdaten bekommen mittlere TTLs (Stunden), je nach Änderungshäufigkeit. Personenbezogene Daten (Warenkorb, Konto) bekommen kurze TTLs oder gar kein Caching. Legen Sie TTLs je Inhaltstyp anhand von Änderungsfrequenz und Konsistenzanforderung fest.
Fazit
Caching ist ein Kraftverstärker für Leistung und Kosten. Eine gut entworfene mehrschichtige Architektur senkt die Datenbanklast um 90 %, drückt die Latenz weltweit unter 50 ms und fängt Lastspitzen ab, die den Ursprungsserver sonst umwerfen würden.
Entscheidend ist, den Zweck jeder Schicht zu verstehen, die Invalidierung abzustimmen und für den Fehlerfall zu entwerfen. Behandeln Sie Caching als vollwertigen Teil Ihrer Architektur: Trefferquoten messen, Löschen automatisieren, Invalidierungswege mit echten Daten testen. Teams, die Caching beherrschen, gewinnen bei Leistung, Kosten und Zuverlässigkeit.
Für E-Commerce-Teams im großen Maßstab ist Caching nicht verhandelbar. Beginnen Sie mit Browser-Cache und versionierten URLs (der einfachste Gewinn), ergänzen Sie Edge-Caching für öffentliche Inhalte, legen Sie Redis für heiße Daten darüber und setzen Sie ereignisgesteuerte Invalidierung für Korrektheit um. Und messen Sie laufend. Holen Sie sich Unterstützung oder nutzen Sie unser Kontaktformular. Die Investition zahlt sich in Millisekunden und in zufriedenen Kunden aus.
Quellen
- web.dev – Prevent Unnecessary Network Requests with HTTP Cache
- Jono Alderson – A Complete Guide to HTTP Caching
- Kinsta – Redis Object Caching for WordPress
- Redis – Guide to Cache Optimization Strategies
- WooCommerce & Cloudflare – Caching Best Practices for Optimal Performance
- Codelit – Cache Invalidation Strategies
- Cloudflare – Cache Rules for WordPress/WooCommerce
- WebHostMost – Redis Reality Check: Why Just Enabling Redis WordPress Does Nothing
Häufige Fragen
Was ist der Unterschied zwischen Browser-Cache und CDN-Cache?
Der Browser-Cache legt Ressourcen lokal auf dem Gerät des Nutzers ab (Zugriff unter 5 ms). Der CDN-Cache legt Inhalte weltweit auf Edge-Servern ab (20–100 ms vom Nutzer entfernt). Der Browser-Cache nützt nur diesem einen Nutzer, der CDN-Cache allen Nutzern einer Region. Nutzen Sie beides: Browser-Cache für statische Assets mit langer TTL, CDN für öffentliche Inhalte mit mittlerer TTL, kein CDN für personalisierte Inhalte.
Woran erkennen wir, ob der Redis-Object-Cache wirklich hilft?
Überwachen Sie die Trefferquote. Gesund sind über 80 %. Liegt sie darunter, hilft Redis womöglich nicht — messen Sie vor der Aktivierung. Prüfen Sie außerdem die Eviction-Rate (Anteil der Einträge, die Redis bei vollem Speicher verwirft). Ist sie hoch, erhöhen Sie den Redis-Speicher oder verringern Sie die Datenmenge. Vergleichen Sie schließlich die Ladezeit vor und nach Redis mit echten Verkehrsdaten.
Sollten wir HTML-Seiten cachen, obwohl sich Inhalte häufig ändern?
Cachen Sie HTML nur für öffentliche, nicht dynamische Seiten (Landingpages, Blogbeiträge, Produktlisten, FAQs). Cachen Sie niemals authentifizierte Seiten (/my-account, /checkout, /dashboard), weil gecachte Daten an andere Nutzer gelangen. Für häufig aktualisierte Inhalte wie Bestandszahlen nutzen Sie kurze TTLs (1–4 Stunden) mit ereignisgesteuerter Invalidierung — oder verzichten auf den Full-Page-Cache und setzen für heiße Daten auf Redis.
