
Let's Encrypt SSL-Zertifikate 2026 – Automatisierung mit Certbot
Let's Encrypt SSL-Zertifikate 2026 automatisieren: Certbot installieren, Renewal per systemd-Timer, Wildcards via DNS-01, Rate Limits und Kosten im Vergleich.
WordPress rendert out of the box jede einzelne Seite dynamisch: PHP lädt und kompiliert Dateien, MySQL beantwortet Dutzende Queries, das Theme baut das HTML zusammen. Auf einem typischen vServer mit 2 vCPU und 4 GB RAM bedeutet das 800–1.400 ms Time to First Byte (TTFB) bei ungecachten Requests. Genau derselbe Server liefert mit einem vollständigen Caching-Stack 40–120 ms TTFB – ein Faktor 10 bis 20, ohne dass eine Zeile Anwendungscode geändert wird.
Das ist 2026 kein Kosmetikthema mehr. Interaction to Next Paint (INP) hat First Input Delay als Core-Web-Vital-Metrik ersetzt, und Google bewertet Ladezeiten weiterhin als Ranking-Signal. Studien aus dem E-Commerce zeigen konsistent: jede zusätzliche Sekunde Ladezeit kostet 7–12 % Conversion. Bei 100.000 monatlichen Besuchern und 2 % Basis-Conversion-Rate sind das mehrere hundert verlorene Bestellungen pro Monat.
Der wirtschaftliche Hebel liegt aber nicht nur im Umsatz, sondern in den Serverkosten. Ein Shop, der 50 Requests/Sekunde ungecacht braucht, benötigt dafür rund 8 vCPU und 16 GB RAM – etwa 60–90 €/Monat bei Hetzner oder Netcup. Mit Full-Page-Cache aus dem RAM stemmt dieselbe Seite 500+ Requests/Sekunde auf einem CX22 für 3,79 €/Monat. Caching ist damit die günstigste Skalierungsmaßnahme überhaupt.
Dieser Guide baut den kompletten Stack von unten nach oben auf: OPcache für PHP-Bytecode, Redis für den Object Cache, Nginx FastCGI für Full-Page-Caching, ein CDN für die Edge – plus Messmethoden, Preisvergleiche und die typischen Fallstricke, an denen 80 % aller Setups scheitern.
Caching ist kein einzelnes Plugin, sondern ein Schichtenmodell. Jede Ebene fängt andere Arbeit ab, und die Wirkung multipliziert sich, statt sich zu addieren. Wer nur ein Plugin installiert und OPcache sowie Redis ignoriert, lässt typischerweise 60 % der möglichen Performance liegen.
| Ebene | Tool | Was gecacht wird | Typische Ersparnis |
|---|---|---|---|
| 1. Bytecode | OPcache (+JIT) | Kompiliertes PHP | 30–50 % CPU-Zeit |
| 2. Object Cache | Redis / Memcached | DB-Queries, Options, Transients | 40–70 % Query-Last |
| 3. Page Cache | Nginx FastCGI / Plugin | Fertiges HTML | 90–98 % TTFB |
| 4. Edge | Cloudflare / Bunny / Fastly | HTML, Assets, Bilder | 50–200 ms Latenz |
Die Reihenfolge beim Aufbau ist wichtig: Erst OPcache, dann Redis, dann Page Cache, zuletzt CDN. Wer mit dem CDN beginnt und dabei einen langsamen Origin behält, verschiebt das Problem nur – jeder Cache-Miss trifft weiterhin einen überlasteten Server, und bei Cloudflare & Co. zahlst du für jeden Miss mit Latenz.
Ein zweiter Grundsatz: Jede Ebene braucht eine saubere Invalidierungsstrategie. Ein Cache, der nach einem Beitrags-Update alte Inhalte ausliefert, ist schlimmer als kein Cache. Dazu später mehr im Abschnitt zu Exclusions.
OPcache ist in jedem modernen PHP 8.x enthalten und meist bereits aktiv, aber mit Standardwerten, die für kleine Blogs gedacht sind. Die Standardeinstellung opcache.memory_consumption=128 reicht für WooCommerce mit 40 Plugins nicht aus – dann kommt es zu ständigen Cache-Evictions und der Bytecode wird neu kompiliert.
Eine praxiserprobte Konfiguration für PHP 8.3/8.4 auf einem Server mit 4 GB RAM:
; /etc/php/8.3/fpm/php.ini
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.save_comments=1
opcache.fast_shutdown=1
opcache.jit=1255
opcache.jit_buffer_size=128M
Die kritischen Werte: max_accelerated_files=20000 deckt auch große Plugin-Stacks ab (WordPress selbst nutzt rund 3.000 Dateien, WooCommerce mit Extensions schnell 12.000). interned_strings_buffer=32 verhindert, dass Strings aus dem Cache fliegen. save_comments=1 ist Pflicht, weil viele Plugins Doctrine- oder PHPUnit-Annotationen zur Laufzeit auslesen.
Achtung bei validate_timestamps=0: PHP prüft dann nicht mehr, ob sich Dateien geändert haben. Das spart pro Request 5–15 ms, bedeutet aber, dass du nach jedem Deployment systemctl reload php8.3-fpm ausführen musst. Automatisiere das in deinem Deploy-Skript, sonst debugst du stundenlang an Änderungen, die „nicht ankommen".
JIT mit opcache.jit=1255 und 128 MB Buffer bringt bei typischen WordPress-Workloads 3–8 % – bei rein CPU-lastigen Plugins (Bildverarbeitung, PDF-Generierung) deutlich mehr. Prüfen lässt sich die Trefferquote mit php -i | grep -i opcache oder einem opcache-status-Script: Zielwert ist eine Hit Rate über 99 % und 0 wasted memory.
Der Object Cache ist die zweite Ebene und der am meisten unterschätzte Hebel. WordPress speichert Options, Transients und Query-Ergebnisse standardmäßig in einem nicht-persistenten Array – jeder Request fragt also dieselben Daten erneut aus MySQL ab. Ein WooCommerce-Shop feuert dabei leicht 120–250 Queries pro Seitenaufruf.
Installation auf Debian/Ubuntu:
apt install redis-server php8.3-redis
systemctl enable --now redis-server
# /etc/redis/redis.conf
maxmemory 512mb
maxmemory-policy allkeys-lru
save ""
appendonly no
tcp-keepalive 60
timeout 300
save "" und appendonly no deaktivieren die Persistenz. Das ist für einen Object Cache korrekt: Geht Redis verloren, füllt WordPress den Cache einfach neu. Persistenz kostet nur I/O und kann bei einem vollen Disk den Server blockieren. allkeys-lru sorgt dafür, dass bei erreichtem maxmemory die ältesten Keys fliegen statt Schreibfehler zu produzieren.
In der wp-config.php oberhalb von /* That's all, stop editing! */:
define('WP_CACHE', true);
define('WP_REDIS_HOST', '127.0.0.1');
define('WP_REDIS_PORT', 6379);
define('WP_REDIS_DATABASE', 0);
define('WP_REDIS_TIMEOUT', 1);
define('WP_REDIS_READ_TIMEOUT', 1);
define('WP_REDIS_MAXTTL', 86400);
define('WP_REDIS_PREFIX', 'hz_');
Danach das Plugin Redis Object Cache (kostenlos) installieren und per WP-CLI aktivieren: wp redis enable. Die Verifikation erfolgt über redis-cli info stats – entscheidend sind keyspace_hits gegen keyspace_misses. Eine Quote von über 90 % Hits ist das Ziel; darunter stimmt meist die maxmemory-Größe nicht oder ein Plugin umgeht den Object Cache.
Für Agenturen mit vielen Sites lohnt sich Object Cache Pro (ab rund 95 US-Dollar/Monat für unbegrenzte Installationen) – es bringt asynchrones Schreiben, bessere Metriken und einen integrierten Page-Cache. Für einzelne Shops reicht die kostenlose Variante vollständig aus.
Die dritte Ebene liefert fertiges HTML direkt aus dem Webserver. Nginx kann das ohne jedes Plugin über fastcgi_cache – das ist die schnellste und ressourcenschonendste Variante, weil PHP-FPM für einen Cache-Hit gar nicht erst anläuft.
# /etc/nginx/conf.d/cache.conf
fastcgi_cache_path /var/cache/nginx/wpcache
levels=1:2 keys_zone=WPCACHE:100m
inactive=60m max_size=10g;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_valid 200 301 302 60m;
fastcgi_cache_valid 404 1m;
fastcgi_cache_use_stale error timeout invalid_header
updating http_500 http_503;
fastcgi_cache_background_update on;
fastcgi_cache_lock on;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
add_header X-FastCGI-Cache $upstream_cache_status;
keys_zone=WPCACHE:100m reserviert 100 MB für Schlüssel-Metadaten – das reicht für rund 800.000 URLs. max_size=10g begrenzt den HTML-Cache auf der Platte. fastcgi_cache_lock on verhindert den gefürchteten Cache-Stampede: Wenn 200 Requests gleichzeitig auf eine leere Cache-URL treffen, rendert nur einer, alle anderen warten. fastcgi_cache_use_stale liefert bei einem PHP-FPM-Absturz weiterhin alte Inhalte aus – der Shop bleibt online, statt 502-Fehler zu werfen.
Der Header X-FastCGI-Cache zeigt dir bei jedem Aufruf HIT, MISS, BYPASS oder EXPIRED. Prüfen mit curl -I https://example.com/. Ohne diesen Header fliegst du blind.
| Kriterium | Nginx FastCGI Cache | Redis Page Cache (Plugin) |
|---|---|---|
| TTFB bei Hit | 15–40 ms | 45–90 ms |
| PHP-FPM nötig? | Nein | Ja |
| Admin-Komfort | Manuell / WP-CLI-Purge | Automatisch |
| RAM-Verbrauch | Platte + 100 MB Metadaten | 1–4 GB RAM |
| Multi-Server | Nein (lokal) | Ja (zentral) |
Für Single-Server-Setups ist Nginx FastCGI klar überlegen. Redis Page Cache gewinnt erst, wenn du hinter einem Load Balancer mehrere Webserver betreibst und einen gemeinsamen, zentralen Cache brauchst.
Wenn du keinen Root-Zugriff hast oder den Komfort der automatischen Invalidierung willst, ist ein Plugin die richtige Wahl. Die Preis- und Funktionslage 2026:
| Plugin | Preis | Full-Page | Redis | CDN-Integration |
|---|---|---|---|---|
| LiteSpeed Cache | 0 € | Ja (nur LiteSpeed/OLS) | Ja | QUIC.cloud |
| WP Rocket | 59 $/Jahr | Ja | Nur mit Add-on | Cloudflare |
| FlyingPress | 60 $/Jahr | Ja | Ja | Bunny, Cloudflare |
| W3 Total Cache | 0 € / 99 $/Jahr Pro | Ja | Ja | Viele |
| WP Super Cache | 0 € | Ja | Nein | Nein |
Empfehlung nach Stack: Läuft dein Server auf OpenLiteSpeed (z. B. bei einem LiteSpeed-basierten Hoster), ist LiteSpeed Cache kostenlos und funktional kaum zu schlagen – ESI, Critical CSS und Bildoptimierung inklusive. Auf Nginx/Apache mit eigenem Root-Zugriff fährst du mit Nginx FastCGI + Redis Object Cache günstiger und schneller. Auf Shared Hosting ohne Root ist WP Rocket oder FlyingPress die pragmatische Wahl.
Eine dringende Warnung: Betreibe niemals zwei Full-Page-Cache-Systeme parallel. WP Rocket plus Nginx FastCGI plus Cloudflare APO erzeugt dreifache Invalidierungslogik – du bekommst inkonsistente Inhalte und debugst Tage. Wähle eine Ebene pro Schicht und dokumentiere sie.
Das CDN ist die vierte Ebene und reduziert vor allem die Latenz für geografisch entfernte Besucher. Ein Nutzer in Singapur wartet auf einen Server in Frankfurt mindestens 180 ms pro Roundtrip – bei sechs Roundtrips sind das über eine Sekunde, bevor überhaupt gerendert wird.
| Anbieter | Preis | PoPs | Besonderheit |
|---|---|---|---|
| Cloudflare Free | 0 € | 330+ | DDoS-Schutz, HTTP/3, Brotli |
| Cloudflare Pro | 20 $/Monat | 330+ | Bildoptimierung, WAF |
| Cloudflare APO | 5 $/Monat | 330+ | HTML-Cache für WordPress |
| Bunny CDN | ab 0,01 $/GB | 119 | Sehr günstig, EU-Fokus |
| Fastly | ab 50 $/Monat | 80+ | VCL, Instant Purge |
Für die meisten WordPress-Sites ist Cloudflare Free plus APO für 5 $/Monat das beste Preis-Leistungs-Verhältnis. APO cached HTML an der Edge und invalidiert automatisch bei neuen Beiträgen – damit sparst du deinem Origin bis zu 90 % der Requests. Wichtig: APO funktioniert nur, wenn du keinen konkurrierenden Page-Cache im Plugin betreibst, der eigene Cache-Header setzt.
Für reine Asset-Auslieferung (Bilder, CSS, JS) ist Bunny CDN mit 0,01 $/GB konkurrenzlos günstig: 1 TB Traffic kostet 10 $. Setze im CDN immer Brotli, HTTP/3 und Early Hints aktiv und konfiguriere Cache-Control-Header mit immutable und einem Jahr TTL für versionierte Assets:
location ~* \.(css|js|woff2|webp|avif)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
Auch mit Redis Object Cache bleiben einige Queries übrig – und die Datenbank ist meist der langsamste Teil des Stacks. Der wichtigste Hebel ist der InnoDB Buffer Pool: Er sollte 60–70 % des verfügbaren RAM belegen.
# /etc/mysql/mariadb.conf.d/99-tuning.cnf
[mysqld]
innodb_buffer_pool_size = 2G
innodb_log_file_size = 512M
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit = 2
max_connections = 150
tmp_table_size = 64M
max_heap_table_size = 64M
Bei 4 GB RAM sind 2 GB Buffer Pool ein guter Wert. innodb_flush_log_at_trx_commit = 2 opfert theoretisch bis zu eine Sekunde Daten bei einem Stromausfall, verdoppelt aber den Durchsatz bei schreibintensiven Workloads – für WordPress mit aktivem Redis-Cache ein akzeptabler Trade-off.
Der MySQL Query Cache existiert in MySQL 8.0 nicht mehr und ist auch in MariaDB ab 10.6 standardmäßig deaktiviert. Setze ihn nicht reaktiv in Betrieb – er skaliert nicht über mehrere Kerne und wird zum Flaschenhals.
Zwei regelmäßige Wartungsschritte bringen zusätzlich 10–20 %: wp transient delete --expired entfernt abgelaufene Transients, die sich sonst in wp_options stapeln. Und die Autoload-Größe sollte unter 800 KB bleiben – prüfen mit:
SELECT SUM(LENGTH(option_value)) AS autoload_size
FROM wp_options WHERE autoload = 'yes';
Alles darüber wird bei jedem Request in den Speicher geladen, auch mit Redis. Ursache sind meist schlecht programmierte Plugins, die ihre Settings ohne autoload=no speichern.
Das ist der Teil, an dem die meisten Setups scheitern. Ein aggressiver Page Cache liefert eingeloggten Kunden den Warenkorb eines anderen aus – oder zeigt nach dem Login noch die „Anmelden"-Navigation. Die Regel lautet: Alles, was pro Nutzer oder pro Session variiert, darf nie gecacht werden.
Diese Pfade gehören immer auf die Bypass-Liste:
/wp-admin/, /wp-login.php, /wp-json/ (außer öffentliche Endpoints)/cart/, /checkout/, /my-account/, ?add-to-cart=wordpress_logged_in_*, woocommerce_cart_hash, wp-postpass_*?preview=true, ?s= (Suche), ?p=In Nginx sieht das so aus:
set $skip_cache 0;
if ($request_method = POST) { set $skip_cache 1; }
if ($query_string != "") { set $skip_cache 1; }
if ($request_uri ~* "/wp-admin/|/cart/|/checkout/|/my-account/|/wp-json/") {
set $skip_cache 1;
}
if ($http_cookie ~* "wordpress_logged_in|woocommerce_cart_hash|wp-postpass_") {
set $skip_cache 1;
}
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
Für die Invalidierung nach Content-Änderungen gibt es drei Strategien: TTL-basiert (einfach, aber bis zu 60 Minuten veraltete Inhalte), Event-basiert über Plugin-Hooks (präzise, aber fehleranfällig) und Purge-per-WP-CLI im Deploy-Skript. In der Praxis kombiniert man alle drei: kurze TTL von 10–15 Minuten für stark frequentierte URLs, Plugin-Purge für Beiträge und manueller Purge nach Deployments.
Ohne Messung ist Caching-Optimierung Raten. Die drei wichtigsten Werkzeuge sind curl für den Cache-Status, ab oder k6 für Lasttests und WebPageTest für die reale Nutzererfahrung.
# Cache-Status prüfen
curl -sI https://example.com/ | grep -i x-fastcgi-cache
# Lasttest: 1000 Requests, 50 parallel
ab -n 1000 -c 50 -H "Accept-Encoding: gzip" https://example.com/
# Mit k6 (moderner, aussagekräftiger)
k6 run --vus 50 --duration 60s script.js
Die Zielwerte, an denen du dich orientieren solltest:
| Metrik | Gut | Akzeptabel | Handlungsbedarf |
|---|---|---|---|
| TTFB (Cache Hit) | < 100 ms | 100–250 ms | > 250 ms |
| LCP (mobil) | < 2,0 s | 2,0–2,5 s | > 2,5 s |
| INP | < 150 ms | 150–200 ms | > 200 ms |
| OPcache Hit Rate | > 99 % | 95–99 % | < 95 % |
| Redis Hit Rate | > 92 % | 85–92 % | < 85 % |
| Queries pro Request | < 30 | 30–60 | > 60 |
Für die Query-Analyse im laufenden Betrieb ist Query Monitor das beste kostenlose Tool – es zeigt pro Request alle Queries, deren Herkunft (Plugin, Theme, Core) und die Dauer. Ergänzend lohnt ein Blick in SHOW FULL PROCESSLIST bei Lastspitzen sowie das Slow Query Log mit long_query_time = 0.5.
Für kontinuierliches Monitoring empfiehlt sich ein externer Uptime- und Performance-Dienst (UptimeRobot kostenlos, Better Stack ab 24 $/Monat) plus Server-Metriken über Netdata oder Prometheus mit Node Exporter. Achte besonders auf Redis-Evictions (evicted_keys in redis-cli info stats) – steigen sie, ist maxmemory zu klein, und der Object Cache verliert genau die Keys, die am häufigsten gebraucht werden.
Fehler 1: Eingeloggte Nutzer sehen fremde Inhalte. Ursache ist fast immer ein fehlender Cookie-Bypass. Prüfe mit einem zweiten Browser, der eingeloggt ist, und kontrolliere den X-FastCGI-Cache-Header – er muss BYPASS zeigen, nicht HIT.
Fehler 2: Änderungen erscheinen nicht nach dem Deployment. Bei opcache.validate_timestamps=0 musst du PHP-FPM reloaden. Ergänze in deinem Deploy-Skript systemctl reload php8.3-fpm && nginx -s reload und einen Cache-Purge.
Fehler 3: Redis läuft voll und evictet ständig. Bei einem großen WooCommerce-Shop mit 50.000 Produkten braucht der Object Cache realistisch 1–2 GB. Setze maxmemory auf 25 % des Server-RAM und prüfe used_memory_human über 24 Stunden, bevor du final konfigurierst.
Fehler 4: CDN cached 404-Fehler. Ein Tippfehler in einer URL, einmal von einem Crawler aufgerufen, wird sonst stundenlang ausgeliefert. Setze im CDN eine kurze TTL für 4xx-Statuscodes (60 Sekunden) und schließe /wp-json/ sowie Query-Strings vom Edge-Cache aus.
Fehler 5: Zu viele Caching-Plugins. WP Rocket + Autoptimize + W3TC gleichzeitig erzeugen widersprüchliche Header und doppeltes Minifying. Ein Plugin pro Aufgabe, nicht mehr. Und Fehler 6: JIT mit opcache.jit=1255 kann bei einzelnen Page-Buildern (Elementor, Divi) zu sporadischen Fatal Errors führen – teste nach dem Aktivieren 48 Stunden lang alle Templates, bevor du live gehst.
Ja, für die meisten Sites. Der Page Cache beschleunigt nur anonyme, gecachte Seitenaufrufe. Sobald ein Nutzer eingeloggt ist, sich etwas in den Warenkorb legt oder eine Seite gecacht werden darf (Checkout, Mein Konto), greift er nicht – und dann laufen alle Queries ungebremst gegen MySQL. Redis Object Cache senkt die Query-Last in diesen Fällen um 40–70 % und schützt dich vor Lastspitzen. Bei reinen Blogs mit wenig dynamischem Traffic kannst du darauf verzichten.
Ein realistisches Setup: Hetzner CX22 (2 vCPU, 4 GB) für 3,79 €, Cloudflare Free für 0 €, LiteSpeed Cache oder Nginx FastCGI + Redis Object Cache für 0 €. Macht insgesamt unter 5 €/Monat und liefert TTFB-Werte unter 100 ms. Wer Komfort will, addiert WP Rocket (59 $/Jahr ≈ 4,50 €/Monat) und Cloudflare APO (5 $/Monat). Ein Shared-Hosting-Tarif mit vergleichbarer Performance kostet typischerweise 15–30 €/Monat.
So selten wie möglich. Bei korrekt konfigurierter Event-Invalidierung musst du nie manuell eingreifen. Als Sicherheitsnetz empfiehlt sich eine TTL von 10–15 Minuten für stark frequentierte URLs und 60 Minuten für den Rest. Manueller Purge ist nur nach Deployments, Theme-Änderungen oder Plugin-Updates nötig – automatisiere das per WP-CLI (wp cache flush, wp litespeed-purge all) im Deployment-Skript.
Nein, im Gegenteil – solange die Invalidierung funktioniert. Google bewertet Ladezeit und Core Web Vitals als Ranking-Faktoren, und ein Cache verbessert LCP und INP messbar. Kritisch wird es nur, wenn du versehentlich gecachte 404-Seiten, veraltete Canonical-Tags oder eingeloggten Nutzern falsche Inhalte auslieferst. Prüfe nach dem Setup die Google Search Console auf Abdeckungsfehler und lasse ein Crawl-Tool (Screaming Frog, 259 €/Jahr) über die Seite laufen.
Redis. Memcached ist minimal schneller bei reinen Get/Set-Operationen, unterstützt aber keine Datenstrukturen, keine Persistenz-Optionen und – entscheidend – keine Key-Prefixes pro Site. Für Multisite-Installationen oder mehrere WordPress-Instanzen auf einem Server ist Redis wegen WP_REDIS_PREFIX und WP_REDIS_DATABASE klar die bessere Wahl. Memcached lohnt nur, wenn du bereits eine Memcached-Infrastruktur betreibst oder extrem wenig RAM zur Verfügung hast.