Der grundlegende Artikel über TTFB verbessern erklärt den Einstieg: besseres Hosting, Caching aktivieren, CDN nutzen. Aber was, wenn du das alles bereits gemacht hast — und dein TTFB trotzdem bei 400–700ms liegt?
Dann bist du an dem Punkt, wo die meisten Performance-Guides aufhören. Dieser Artikel beginnt dort. Wir gehen in die Tiefe: Datenbankoptimierung, serverseitiges PHP-Tuning, Edge Computing und Connection-Pooling. Das sind die Maßnahmen, die den Unterschied zwischen 400ms und 80ms ausmachen.
Zielwert: Google bewertet TTFB unter 800ms als "akzeptabel", unter 200ms als "gut". Für kompetitive Rankings und optimale Core Web Vitals ist unter 200ms das Ziel — und unter 100ms ist für gecachte Seiten realistisch.
TTFB-Diagnostik: Wo verlierst du Zeit?
Bevor du optimierst, musst du wissen, wo deine 600ms verloren gehen. TTFB setzt sich aus mehreren Komponenten zusammen:
| Komponente | Was passiert | Typischer Anteil |
|---|---|---|
| DNS-Lookup | Domain → IP-Adresse auflösen | 10–50ms |
| TCP-Verbindung | 3-Way-Handshake | 20–80ms |
| TLS-Handshake | HTTPS-Verschlüsselung aushandeln | 30–100ms |
| Server-Verarbeitung | PHP/Node/Python ausführen, DB-Queries | 50–800ms+ |
| Netzwerk-Latenz | Physikalischer Weg Server → Browser | 10–200ms |
Die Server-Verarbeitungszeit ist meist der größte Faktor und am besten optimierbar. Um sie zu isolieren, nutze die Chrome DevTools: Öffne den Network-Tab, klicke auf den HTML-Dokument-Request, und schau unter "Timing". Der Abschnitt "Waiting (TTFB)" zeigt die reine Server-Verarbeitungszeit.
Server-Log-Analyse für die Ursache
Wenn die Server-Verarbeitung 400ms+ dauert, prüfe deine Server-Logs auf langsame Requests. In Nginx:
# nginx.conf: Slow-Request-Log aktivieren
http {
log_format main '$remote_addr - $request_time $upstream_response_time '
'"$request" $status';
access_log /var/log/nginx/access.log main;
}
# Dann im Shell: Requests über 500ms finden
awk '$3 > 0.5 {print $0}' /var/log/nginx/access.log | sort -k3 -n -r | head -20
Welche URLs tauchen wiederholt auf? Das sind deine Optimierungsziele.
Maßnahme 1: Edge-Caching mit CDN-Rules
Standard-Caching mit Nginx oder Varnish speichert im eigenen Rechenzentrum. Edge-Caching bedeutet: der Cache sitzt in 200+ Edge-Locations weltweit — Nutzer in München bekommen Antworten vom Frankfurter Edge-Node, nicht vom Server in New York.
Das ist der größte Einzelhebel für globale TTFB-Verbesserung. Cloudflare, Fastly und BunnyCDN bieten Edge-Caching.
Cloudflare Page Rules für maximales Caching
# .htaccess / Nginx: Cache-Control-Header für statische Assets
# Wichtig: Diese Dateien werden von Cloudflare gecacht
location ~* \.(css|js|jpg|jpeg|png|gif|svg|woff2|ico)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
}
# HTML-Seiten: Kurzlebiger Cache (oder kein Cache bei dynamischen Seiten)
location / {
add_header Cache-Control "public, max-age=300, s-maxage=3600";
# s-maxage: Nur im CDN (Cloudflare) gecacht, nicht im Browser
}
Mit s-maxage=3600 wird die Seite 60 Minuten im Cloudflare-Cache gehalten. Für Blogs und statische Seiten ist das ideal — TTFB sinkt auf 10–30ms.
Vorsicht bei personalisierten Inhalten: Seiten mit Warenkorb, Login-Status oder nutzerspezifischen Daten dürfen nicht gecacht werden. Nutze Cache-Control: private, no-store für diese Seiten oder Cloudflare's "Bypass Cache"-Rule für authentifizierte Nutzer.
Stale-While-Revalidate für immer frischen Cache
# Modern: Stale-While-Revalidate
# Seite sofort ausliefern, im Hintergrund erneuern
add_header Cache-Control "public, max-age=60, stale-while-revalidate=3600";
# Bedeutet:
# - 60s: Aus Cache ohne Check ausliefern
# - 3600s: Veraltete Version ausliefern WHILE neuer im Hintergrund geladen wird
# → Nutzer wartet nie auf Cache-Miss
Maßnahme 2: PHP-OPcache maximieren
Jeder PHP-Request kompiliert standardmäßig das PHP-Script neu — das kostet 50–200ms pro Request. OPcache speichert den kompilierten Bytecode im RAM. Das ist eine der einfachsten und wirksamsten Maßnahmen für PHP-basierte Websites (WordPress, Drupal, Laravel).
; php.ini: OPcache optimal konfigurieren
[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=256 ; RAM in MB (für großen WordPress-Sites: 256-512)
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=0 ; 0 = nie prüfen (maximale Performance)
; Änderungen: Cache via CLI manuell leeren
opcache.validate_timestamps=0 ; Timestamps nicht prüfen (Prod-Umgebung)
opcache.fast_shutdown=1
opcache.jit=1255 ; PHP 8+: JIT-Compiler aktivieren
opcache.jit_buffer_size=128M ; JIT-Buffer: mindestens 64M
Mit JIT (PHP 8+) können rechenintensive Seiten nochmals 10–30% schneller werden. Prüfe ob OPcache aktiv ist:
<?php
echo opcache_get_status()['opcache_enabled'] ? 'OPcache aktiv' : 'OPcache inaktiv';
echo "\nHit-Rate: " . opcache_get_status()['opcache_statistics']['opcache_hit_rate'] . "%";
?>
Erwartete Verbesserung: WordPress-Seiten ohne OPcache: 300–500ms TTFB. Mit OPcache: 80–150ms TTFB. Das ist oft die größte Einzelmaßnahme für PHP-Sites.
Maßnahme 3: Datenbankoptimierung
Wenn OPcache aktiv ist und TTFB trotzdem hoch bleibt, sind Datenbank-Queries der Schuldige. Jeder unkomplizierte WordPress-Seitenaufruf macht 20–80 SQL-Queries. Eine einzelne langsame Query (ohne Index, über große Tabelle) kann 200ms+ kosten.
MySQL Slow Query Log aktivieren
# my.cnf / my.ini:
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 0.1 ; Queries über 100ms loggen
log_queries_not_using_indexes = 1
# Dann: Top-Täter analysieren
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
Fehlende Indizes ergänzen
Das häufigste Problem: Queries über große Tabellen ohne Index. Erkennbar an type: ALL in EXPLAIN:
-- Problematische Query erkennen
EXPLAIN SELECT * FROM wp_posts
WHERE post_status = 'publish' AND post_type = 'post'
ORDER BY post_date DESC LIMIT 10;
-- Wenn "type: ALL" und "rows: 50000" → fehlender Index
-- Index ergänzen:
ALTER TABLE wp_posts
ADD INDEX idx_status_type_date (post_status, post_type, post_date);
WordPress: Object Cache mit Redis
WordPress macht bei jedem Request hunderte DB-Queries für Options, Transients und Meta-Daten. Redis als persistenter Object-Cache eliminiert 70–90% davon:
# wp-config.php
define('WP_REDIS_HOST', '127.0.0.1');
define('WP_REDIS_PORT', 6379);
define('WP_REDIS_TIMEOUT', 1);
define('WP_REDIS_READ_TIMEOUT', 1);
define('WP_REDIS_DATABASE', 0);
# Redis installieren (Ubuntu/Debian):
apt install redis-server php-redis
systemctl enable --now redis-server
# Dann: WP Redis Plugin aktivieren
Messbare Verbesserung: WordPress ohne Redis: 40–80 DB-Queries pro Seitenaufruf. Mit Redis: 5–15 DB-Queries. TTFB sinkt typischerweise um 100–300ms.
Maßnahme 4: Connection Pooling
Jede PHP-Datenbankverbindung hat einen Overhead von 5–20ms für den Verbindungsaufbau. Bei 100 gleichzeitigen Nutzern werden 100 separate Verbindungen aufgebaut — und MySQL-Server haben oft ein Limit von 100–150 Verbindungen, danach kommen Timeouts.
Connection Pooling löst das: Ein Pool von offenen Verbindungen wird wiederverwendet. PgBouncer (PostgreSQL) und ProxySQL (MySQL) sind die Standard-Lösungen.
# ProxySQL-Konfiguration (MySQL):
# /etc/proxysql.cnf
mysql_servers =
(
{
address="127.0.0.1",
port=3306,
hostgroup=0,
max_connections=20 ; Maximale DB-Verbindungen
}
)
mysql_users =
(
{
username="wordpress",
password="geheim",
default_hostgroup=0,
max_connections=500 ; Max gleichzeitige Clients
}
)
# Verbindungspool-Einstellungen
mysql_variables=
{
connection_delay_multiplex_ms=0
multiplexing=1 ; Connection Multiplexing aktivieren
}
PHP: Persistente Verbindungen
Für einfachere Setups ohne ProxySQL: persistente PDO-Verbindungen in PHP.
<?php
$pdo = new PDO(
"mysql:host=localhost;dbname=mydb",
"user",
"password",
[
PDO::ATTR_PERSISTENT => true, // Verbindung im Pool behalten
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]
);
?>
Achtung: Persistente PDO-Verbindungen können unter PHP-FPM zu Problemen führen, wenn Transaktionen nicht korrekt abgeschlossen werden. Teste sorgfältig unter Last.
Maßnahme 5: Server-Side Prerendering und HTML-Streaming
HTML Streaming (Early Flush)
Standard: PHP verarbeitet alles, dann sendet es das fertige HTML. Mit Early Flush sendest du das <head>-Element sofort, während die Seite noch gerendert wird. Der Browser kann CSS und Fonts sofort laden.
<?php
// Preload-Header sofort senden (HTTP/2 Push Alternative)
header('Link: </styles.css>; rel=preload; as=style');
header('Link: </fonts/inter.woff2>; rel=preload; as=font; crossorigin');
// HEAD sofort ausgeben
echo '<!DOCTYPE html><html><head>';
echo '<link rel="stylesheet" href="/styles.css">';
echo '</head><body>';
// Puffer leeren → Browser empfängt HEAD und startet CSS-Download
ob_flush();
flush();
// Jetzt erst DB-Query ausführen
$content = getSlowDatabaseContent();
echo $content;
echo '</body></html>';
?>
Dieses Muster reduziert das wahrgenommene TTFB, weil der Browser den CSS-Download startet, während der Server noch rechnet. Der LCP-Wert verbessert sich oft um 200–400ms.
Maßnahme 6: DNS-Prefetch und Preconnect
Der DNS-Lookup-Teil des TTFB lässt sich auf der Client-Seite minimieren. Wenn du externe Ressourcen lädst (Google Fonts, Analytics, CDN-Assets), veranlasse den Browser, die DNS-Auflösung und TCP-Verbindung im Voraus aufzubauen:
<!-- Im HTML-Head: -->
<!-- DNS-Lookup vorab ausführen -->
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://www.googletagmanager.com">
<!-- TCP + TLS vorab aufbauen (stärker als dns-prefetch) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Ressource vorab laden (höchste Priorität) -->
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
Maßnahme 7: Webserver-Tuning (Nginx)
Standard-Nginx-Konfigurationen sind für Kompatibilität optimiert, nicht für maximale Performance. Diese Anpassungen helfen bei High-Traffic-Sites:
# nginx.conf: Performance-Tuning
worker_processes auto; # Eine Worker-Process pro CPU-Kern
worker_connections 2048; # Max Verbindungen pro Worker
# Sendfile + TCP Nopush: Effizientere Dateiübertragung
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Keep-Alive: Verbindungen länger offen halten
keepalive_timeout 65;
keepalive_requests 1000; # Mehr Requests pro Verbindung
# Puffering: Vollständige Antwort aus Upstream cachen
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
# Gzip für alle Textformate
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript
text/xml application/xml image/svg+xml;
# Worker-File-Descriptor-Limit erhöhen
worker_rlimit_nofile 65535;
Die TTFB-Optimierungsreihenfolge
Du willst den maximalen Impact mit minimalem Aufwand. Hier die Priorisierung nach Effort/Impact-Verhältnis:
- PHP-OPcache aktivieren (30 Minuten, größter Impact für PHP-Sites)
- Redis Object Cache für WordPress (1 Stunde, 100–300ms Verbesserung)
- CDN mit Edge-Caching aktivieren (2 Stunden, für statische Inhalte: 10–30ms TTFB)
- Datenbankindizes optimieren (2–4 Stunden, sehr variabel)
- HTTP/2 & HTTP/3 aktivieren (1 Stunde, Verbindungs-Overhead reduzieren)
- Connection Pooling (4+ Stunden, nur bei >50 gleichzeitigen Nutzern relevant)
- HTML Streaming (2 Stunden, vor allem bei datenbankintensiven Seiten)
Prüfe nach jeder Maßnahme das Ergebnis mit unserem Core Web Vitals Checker oder PageSpeed Insights — und stoppe, wenn du unter 200ms bist. Weitere Optimierungen bringen dann marginal Returns.
TTFB und LCP: Der Zusammenhang
TTFB ist die Basis für alle anderen Performance-Metriken. Ein hoher TTFB bedeutet zwingend ein hohes LCP — das Hauptbild oder der Haupttext kann erst dann geladen werden, wenn die HTML-Antwort angekommen ist. 200ms TTFB + 200ms LCP-Ressource = 400ms LCP. 700ms TTFB + 200ms LCP-Ressource = 900ms LCP. Das ist der Unterschied zwischen "gut" und "schlecht" bei den Core Web Vitals auf Mobile.
Für eine vollständige Performance-Diagnose nutze den Core Web Vitals Checker — er zeigt TTFB, FCP, LCP und alle anderen Metriken direkt via PageSpeed-Insights-API.
Und wenn du sicherstellen willst, dass dein Server das schnellste verfügbare Protokoll nutzt, prüfe mit dem HTTP/2 & HTTP/3 Checker ob HTTP/2 oder HTTP/3 aktiv ist — das ist ein weiterer wichtiger Hebel für niedrige TTFB-Werte.