TTFB-Request-Dauer: Server-Verarbeitungszeit verkürzen
Der Server-Teil der TTFB: wie DevTools und web-vitals ihn nennen, wie Server-Timing den langsamen Schritt zeigt und warum ein Page-Cache an erster Stelle steht.
- Gut ≤ 0,8 s
- Verbesserungswürdig ≤ 1,8 s
- Schlecht > 1,8 s
Teilen
Request-Dauer in Kürze
Die Request-Dauer ist der letzte der fünf Teile der Time to First Byte (TTFB): vom Absenden des HTML-Requests bis zum Eintreffen des ersten Bytes. Sie besteht aus dem Seitenaufbau auf dem Server plus einem Roundtrip über das Netzwerk. Auf den meisten Websites ist sie der größte Teil der TTFB: Optimiere sie zuerst, angefangen mit einem Page-Cache.
Was ist die Request-Dauer und entspricht sie „Waiting (TTFB)“ in den DevTools?
Die Request-Dauer ist das, was die Chrome DevTools im Timing-Tab des Network-Panels als „Waiting for server response“ anzeigen (in älteren Versionen „Waiting (TTFB)“): ein Roundtrip Netzwerklatenz plus die Zeit, die der Server zum Vorbereiten der Antwort gebraucht hat. Die web-vitals-Bibliothek meldet denselben Teil als requestDuration, CoreDash als Request in seinem Phasen-Breakdown und Lighthouse als Server-Antwortzeit.
Sie beginnt, sobald die Verbindung zum Server steht, und endet, wenn das erste Byte des HTML den Browser erreicht. Davor liegen die anderen vier Teile der Time to First Byte: Waiting, Cache, DNS und Connection. Dieser Waiting-Teil besteht hauptsächlich aus Weiterleitungen vor dem Request; er ist nicht das „Waiting“ der DevTools.
Bei 82 der 86 CoreDash-Websites mit mindestens 1.000 mobilen Seitenaufrufen in den 28 Tagen bis zum 9. November 2026 war der Request beim 75. Perzentil der größte Teil der TTFB.
Was macht der Server, während der Browser wartet?
Der Request wandert zum Server und das erste Byte zurück; dazwischen baut der Server die Seite:
- Routing: Der Webserver, etwa Nginx oder Apache, übergibt den Request an die Anwendung.
- Start-up: Die Anwendung lädt ihren Code; WordPress lädt für jede generierte Seite seinen Core, jedes aktive Plugin und das Theme.
- Daten: Die Anwendung fragt ihre Datenbank ab und ruft andere Dienste auf, etwa eine Bestands- oder Preis-API.
- HTML: Das Template baut aus diesen Daten die Seite.

Ein ungecachter Erstbesuch auf einer WordPress-Seite, gemessen in Chrome. Von den 875 ms TTFB entfielen 657 ms auf den Request.
Bei diesem Aufruf dauerte die Verbindung 20 ms für zwei Roundtrips (TCP und TLS) – ein Roundtrip lag also bei rund 10 ms. Etwa 645 der 657 ms brauchte der Server, um die Seite zu bauen. In Servernähe besteht die Request-Dauer fast nur aus Serverzeit; weiter entfernte Besucher warten zusätzlich auf den Roundtrip.
Bevor das erste Byte des HTML eintrifft, kann nichts gerendert werden. Die Request-Dauer verlängert deshalb auch den Largest Contentful Paint.
Welcher Schritt auf dem Server ist langsam? Server-Timing zeigt es
Ein Server-Timing-Header schickt die serverseitigen Messwerte direkt mit dem HTML mit – ein Eintrag pro Schritt: Datenbank, Template, externe API, Cache-Hit oder -Miss. Die Chrome DevTools zeigen die Einträge im Timing-Tab des HTML-Requests unter „Waiting for server response“ an, und ein RUM-Tool sammelt sie bei deinen Besuchern ein.
Server-Timing: db;dur=53.2;desc="Database", tpl;dur=18.7;desc="Template", cache;desc="MISS"

Ein Aufruf auf einer lokalen WordPress-Testinstallation, bei geöffneten DevTools langsamer: Die beiden Server-Timing-Einträge von 27,8 und 27,1 ms liegen innerhalb der 59 ms, die der Browser auf den Server gewartet hat.
Jeder, der die DevTools öffnet, kann den Header lesen. Sende nur Namen und Dauern der Schritte, niemals eine Query, einen Dateipfad oder interne Hostnamen – oder liefere den Header nur an eingeloggte Mitarbeiter aus (MDN).
Server-Timing in PHP
Messe jeden Schritt mit hrtime(true) und sende den Header vor der Seite:
$t = hrtime(true);
$products = $pdo->query('SELECT * FROM products WHERE active = 1')->fetchAll();
$db = (hrtime(true) - $t) / 1e6;
$t = hrtime(true);
$html = renderTemplate('product-list', ['products' => $products]);
$tpl = (hrtime(true) - $t) / 1e6;
header(sprintf('Server-Timing: db;dur=%.1f;desc="Database", tpl;dur=%.1f;desc="Template"', $db, $tpl));
echo $html;
PHP sendet seine Header mit der ersten Ausgabe, die den Server verlässt. Ein späterer header()-Aufruf wird mit einer „headers already sent“-Warnung verworfen; Templates, die direkt ausgeben, brauchen daher Output-Buffering.
Server-Timing in Node.js und Express
Setze den Header in Express vor res.send():
app.get('/products', async (req, res) => {
const t0 = performance.now();
const products = await db.query('SELECT * FROM products WHERE active = 1');
const t1 = performance.now();
const html = renderTemplate('product-list', { products });
const t2 = performance.now();
res.set('Server-Timing',
`db;dur=${(t1 - t0).toFixed(1)};desc="Database", tpl;dur=${(t2 - t1).toFixed(1)};desc="Template"`);
res.send(html);
});
Node sendet die Header mit dem ersten res.write(). Setze Server-Timing bei einer Streaming-Route vor dem ersten Schreibvorgang: Später wirft Node ERR_HTTP_HEADERS_SENT.
Wie misst du die Request-Dauer?
Die Request-Dauer deiner Besucher stammt aus dem Real User Monitoring (RUM): CoreDash zeigt Request im Phasen-Breakdown der TTFB-Seite pro Seite an, und die web-vitals-Bibliothek liefert requestDuration in ihrer TTFB-Attribution.
Google definiert keinen Grenzwert für die Request-Dauer; der Lighthouse-Hinweis „Document request latency“ warnt ab einer Server-Antwortzeit von über 600 ms. Über alle mobilen Seitenaufrufe der 133 CoreDash-Websites mit Smartphone-Daten hinweg lag der Request-Anteil in den 28 Tagen bis zum 9. November 2026 beim 75. Perzentil bei 404 ms.
In deinem eigenen Code liefert die web-vitals-Bibliothek auch die Server-Timing-Einträge, mit denen die Seite ausgeliefert wurde:
import { onTTFB } from 'web-vitals/attribution';
onTTFB(({ value, attribution }) => {
console.log('TTFB', Math.round(value), 'ms');
console.log('Request duration', Math.round(attribution.requestDuration), 'ms');
const nav = attribution.navigationEntry;
if (nav) {
if (nav.finalResponseHeadersStart) { // Chrome 133 and later
console.log('Final response headers at', Math.round(nav.finalResponseHeadersStart), 'ms');
}
console.table((nav.serverTiming || []).map(({ name, duration }) => ({ name, duration })));
}
});
Beide Zahlen stammen aus der Navigation Timing API: TTFB ist responseStart des Navigation-Entrys, und web-vitals berechnet requestDuration aus TTFB minus connectEnd. Die serverTiming-Liste des Eintrags enthält die Werte des Headers als PerformanceServerTiming-Objekte (die Server-Timing-API im Browser), sodass ein RUM-Script sie mit jedem Pageview mitsenden kann.

CoreDash, TTFB auf Smartphones aufgeteilt in die fünf Teile für acme-pagespeed.com: Achte auf den längsten Balken, hier Request.
103 Early Hints lassen die Request-Dauer kurz aussehen. Chrome zählt einen 103-Status als erstes Byte, sodass TTFB und Request-Dauer bereits enden, wenn der Hint eintrifft – während der Server noch an der Seite baut. Shopify sendet sie standardmäßig, ebenso Cloudflare bei aktivierten Early Hints. Erst finalResponseHeadersStart des Navigation-Entrys oder ein Server-Timing-Eintrag zeigen die tatsächliche Serverzeit; 103 Early Hints erklärt die Einrichtung.
Ein APM oder OpenTelemetrys http.server.request.duration misst innerhalb der Anwendung, ohne das Netzwerk und Warteschlangen davor – RUM zeigt daher eine höhere Request-Dauer. Ein einzelner Aufruf in den DevTools („Waiting for server response“) ist nur ein Cache-Hit oder -Miss auf deinem eigenen Rechner; field data erfasst jeden Miss und jeden weit entfernten Besucher. Langsamen TTFB prüfen und beheben zeigt, wie du Seiten und Besucher mit langsamer Request-Phase findest.
Warum liefert der Server das erste Byte so langsam aus?
Auf den meisten Websites bedeutet eine langsame TTFB: Der Server baut die Seite für jeden Besucher neu auf. Es gibt keinen Page-Cache, oder der Besucher umgeht ihn. Seiten, die sich nicht cachen lassen, sind wegen ihrer Rechenarbeit langsam: eine träge Query, eine externe API, auf die die Seite wartet, oder zu wenig CPU.
| Was du siehst | Typische Ursache | Wo du nachschaust |
|---|---|---|
| Auf jeder Seite langsam, ausgeloggt | Kein Page-Cache oder Cache-Misses | Der Cache-Header: HIT oder MISS |
| Eingeloggt oder mit Warenkorb langsam | Seite lässt sich nicht cachen | Server-Timing |
| Langsam bei Links aus Ads und Mails | Query-String nicht im Cache | Die URL mit und ohne ?gclid= |
| Langsam auf Such- und Account-Seiten | Langsame Query oder externer Aufruf | Server-Timing, Query Monitor |
| Nah dran schnell, aus der Ferne langsam | Der Roundtrip zu deinem Server | RUM nach Ländern |
| Von einem Tag auf den anderen langsamer | Ein Release oder defekter Cache | Trend des Request-Anteils im RUM |
| Langsam nach einer ruhigen Phase | Abgelaufener Cache oder Cold-Start | Erster Aufruf im Vergleich zum zweiten |
Wie reduzierst du die Request-Dauer?
Fang mit einem Page-Cache an. Eine gespeicherte Kopie der Seite erspart dem Server die Arbeit – und diese Arbeit macht auf den meisten Websites den größten Teil einer langsamen Time to First Byte (TTFB) aus. Seiten, die sich nicht cachen lassen, erfordern einen schnelleren Server.
WordPress und WooCommerce
Aktiviere den Page-Cache in WP Rocket, LiteSpeed Cache oder bei deinem Hoster. Mein Plugin, WP Core Web Vitals, liefert die gecachte Seite aus, bevor WordPress und die restlichen Plugins laden – etwa fünfmal schneller, als dieselbe Seite aus WordPress heraus zu bedienen.
Prüfe das Ergebnis abgemeldet in einem privaten Fenster: Eingeloggte Nutzer, ein Warenkorb-Cookie und unbekannte Query-Strings umgehen den Cache.
Auf einer lokalen WordPress-Testinstallation mit einem Standard-Theme senkte der Page-Cache den Request-Anteil der Startseite von 31 ms auf rund 1 ms (Median aus jeweils 15 Aufrufen). Eine echte Website braucht länger zum Erstellen einer Seite; ihre gecachte Kopie wird ähnlich schnell ausgeliefert.

Eine lokale Installation hat kein Netzwerk, beide Balken zeigen also die Arbeit des Servers.
Eine Mitglieder-Website, auf der alle eingeloggt sind, oder ein Shop, in dem die meisten Besucher einen Warenkorb haben, profitiert kaum von einem Page-Cache: Jeder Request bedeutet dort PHP- und Datenbankarbeit. Ein Object-Cache wie Redis hält wiederholte Datenbankergebnisse im Speicher; bei vielen Hostern genügt ein Klick oder eine Anfrage an den Support. Query Monitor listet die langsamen Datenbankabfragen und das verursachende Plugin auf.
Shopify
Der Server, sein Cache und das CDN gehören Shopify. In deiner Verantwortung liegt das Liquid des Themes und seiner App-Blocks, die Shopify auf seinen Servern rendert. Der Shopify Theme Inspector for Chrome zeigt, welche Section oder welches Snippet lange braucht: Kürze den Code oder ersetze die App, die ihn einfügt.
Ein Page-Cache vor deiner Anwendung
Ein Reverse Proxy, das CDN oder ein Cache, der vor deinem Framework anspringt, erspart der Anwendung die Arbeit. Dieser Header erlaubt einem CDN oder Proxy, das HTML zehn Minuten lang vorzuhalten und noch eine Minute lang auszuliefern, während eine frische Kopie geholt wird – und zwingt den Browser, bei jedem Besuch neu nachzufragen:
Cache-Control: public, max-age=0, s-maxage=600, stale-while-revalidate=60
Ich habe mein WordPress-Plugin die gecachte Datei nicht direkt über Nginx oder Apache ausliefern lassen: Das wäre kaum schneller gewesen, und jede Prüfung auf Cookies und URL-Parameter hätte in die Server-Konfiguration kopiert werden müssen.
Ein Set-Cookie bei jeder Antwort, etwa für eine Session oder einen A/B-Test, verhindert oft das Cachen im CDN. Vary: Cookie verlangt eine eigene Kopie pro Cookie-Wert, was bei Analytics-Cookies so gut wie keine Hits bedeutet. Jeder neue gclid- oder utm_source-Wert aus einer Anzeige ist eine neue URL, es sei denn, der Cache ignoriert diese Parameter. Um die Serverzeit ohne Cache zu messen, rufe die Seite mit einem Parameter auf, den deine Caches nicht ignorieren (etwa ?test= mit jedes Mal neuem Wert), und prüfe, ob alle Cache-Header MISS melden.
Ein CDN, das das HTML cacht
Ein CDN, das das HTML cacht, antwortet von einem Server nahe beim Besucher. Die Time to First Byte enthält dann weder den Weg zu deinem Server noch dessen Arbeit. Ein CDN, das nur Bilder und Scripte cacht, leitet jeden HTML-Request an deinen Server weiter. Bei Cloudflare wird HTML nur über eine Cache Rule gecacht, oder über APO für WordPress: Cloudflare für die Core Web Vitals konfigurieren zeigt die Einstellungen. Code am CDN-Edge, der deine Datenbank braucht, wartet trotzdem auf den Roundtrip dorthin.
Seiten, die für jeden Besucher gebaut werden
Seiten für eingeloggte Nutzer, der Warenkorb und Suchergebnisse können nicht aus einem Page-Cache kommen; Server-Timing benennt den langsamen Schritt. Für die Datenbank: ein Index für die langsame Query und eine Abfrage für eine Liste statt einer pro Eintrag (das N+1-Problem). Wartet eine Seite auf eine Datenbank oder eine API in einem anderen Rechenzentrum, verlängert dieser Roundtrip jeden Request: Cache die Antwort und rufe voneinander unabhängige Dienste parallel auf.
const [stock, prices] = await Promise.all([getStock(id), getPrices(id)]);
Mails versenden, Logs schreiben und Bestände abgleichen können warten: Erledige das nach der Response oder über eine Queue.
Der Server und das Hosting
Ein Hosterwechsel ist sinnvoll, wenn Server-Timing und deine RUM-Daten zeigen, dass der Server selbst zu langsam ist: Gecachte Seiten sind schnell, aber bei ungecachten dauert jeder Schritt lang. Viele Hosting-Upgrades bringen nur mehr Speicherplatz; ein schnellerer Server braucht mehr CPU und Arbeitsspeicher. Nutze eine aktuelle PHP-Version mit aktivem OPcache. Eine Serverless-Funktion wartet nach einer Ruhephase auf einen Cold-Start: Halte eine Instanz warm oder schalte einen Page-Cache davor.
JavaScript-Frameworks (Next.js, Nuxt, SvelteKit)
Ein JavaScript-Framework, das jede Seite serverseitig pro Request rendert, liefert die TTFB einer ungecachten Seite. In der Praxis wird CMS-Content oft für jede Seite live abgefragt, gepaart mit Cache-Control: private oder no-store – womit auch das CDN kein HTML speichern kann. Rendere Seiten statisch oder gecacht, wo immer der Inhalt es erlaubt (in Next.js über use cache), cache die CMS-Abfragen und lass das CDN das HTML vorhalten. Streame dynamische Teile hinter <Suspense>, damit der Head mit den Stylesheets zuerst rausgeht. Cookies oder Header, die in einem Layout ausgelesen werden, zwingen jede darunterliegende Seite zum Rendern pro Request.
Wurde der Server für echte Besucher schneller?
Teste zuerst einen Aufruf ausgeloggt im privaten Fenster, danach mit ?gclid= und einem neuen Wert. Die Response-Header sollten einen Cache-Hit (cf-cache-status: HIT bei Cloudflare, X-CWV-Cache: HIT bei WP Core Web Vitals) und deine Server-Timing-Einträge anzeigen; ein MISS beim Aufruf mit ?gclid= bedeutet, dass Besucher über Ads auf den Server warten müssen. Nach einem Release muss das HTML auch im CDN gelöscht werden, sonst erhalten Besucher weiterhin die alte Seite.
Am nächsten Tag zeigt der Request-Anteil in deinen RUM-Daten die Veränderung. PageSpeed Insights zeigt nur die gesamte TTFB über die letzten 28 Tage und reagiert entsprechend träge.
Manche langsamen Requests erfordern mehr als einen Cache oder eine Einstellung: ein Shop, in dem jeder Besucher einen Warenkorb hat, oder ein Hoster bzw. Backend, an das du nicht rankommst. In einer Core Web Vitals Power Hour analysieren wir deine Server-Timing-Einträge sowie die langsamsten Seiten und legen fest, was der Server als Erstes sein lassen kann – und wer das umsetzt: dein Hoster oder dein Entwickler.

Brauchst du eine schnellere Website?
Ich bin Arjen und mache seit 17 Jahren langsame Websites schnell. Wenn du auf Probleme stößt, die du nicht selbst lösen kannst, schick mir deine URL und wir reden darüber.
Schick mir deine URL
Warum funktioniert unser Fix nicht?
Manchmal liefert das CDN noch das alte HTML aus, oder der Fix steckt im Desktop-Template und Mobilgeräte nutzen ein anderes. Schick mir deine URL und das Problem, dann antworte ich mit ein paar Terminvorschlägen. Ich prüfe zuerst deine Field Data, dann arbeiten wir eine Stunde an deiner Website, und innerhalb eines Tages hast du meine Notizen schriftlich. 350 € zzgl. MwSt.
Schick mir deine URLKein Entwickler für den Fix? Ich mache die Arbeit selbst, auf einer Kopie deiner Website.