TTFB Under 200ms: What I Actually Found When I Audited 50 Sites
Server-side timing breakdown — DNS, TCP, TLS, TTFB, download — across 50 real sites. What the numbers mean, what moves them, and how ByteWaveNetwork's Page Speed Inspector surfaces them in seconds.
Last quarter I was brought in to diagnose a WooCommerce store that was "slow" according to the client's Google Search Console Core Web Vitals report. Their LCP was sitting at 4.2 seconds. The dev team had already spent two weeks optimising images, deferring scripts, and implementing lazy loading — the usual frontend checklist. Nothing moved the needle more than 0.1 seconds.
I ran the URL through ByteWaveNetwork's Page Speed Inspector and got my answer in about eight seconds: TTFB was 1,140ms. DNS resolved in 12ms. TCP connected in 28ms. TLS negotiated in 94ms. The server itself was taking over a second just to generate the first byte. No amount of image compression was going to fix that. It was a PHP object-cache miss on every single page load because object-caching had been silently disabled during a plugin update three weeks earlier. Fixed in an afternoon. LCP dropped to 1.8 seconds by the following morning.
That experience crystallised something I'd suspected for a while: most frontend performance work is wasted effort when the server timing hasn't been measured properly first. So I spent the next few weeks running 50 different URLs — e-commerce stores, SaaS marketing pages, news sites, Next.js apps, static sites — through the tool to build a real picture of what "normal" looks like and where the common failure points sit.
Key Takeaways
- TTFB above 600ms almost always points to a server-side problem, not a frontend one — stop optimising images first.
- TLS handshakes routinely add 100–300ms on first connection; HTTP/2 + session resumption significantly reduces this.
- Next.js ISR pages showing
Cache-Control: max-age=0, must-revalidateare not cache misses — that's deliberate CDN behaviour. - Render-blocking resources only hurt you when they sit above the fold; a blocking script in the footer is a false alarm.
- The Page Speed Inspector measures from a real server, not a simulated environment — results reflect actual network conditions.
What the Tool Actually Does (And Why That Matters)
Most online speed tools run a headless browser in a lab and simulate a connection. That's useful for Lighthouse scores, but it tells you nothing about what a real user in a real data centre region experiences at the protocol level.
The Page Speed Inspector works differently. It makes an actual server-side HTTP request to your URL and measures every phase of the connection independently: DNS resolution, TCP handshake, TLS negotiation, time to first byte, and content download. It also fires a separate TLS ALPN probe to detect whether HTTP/2 is genuinely available — not just advertised in headers after the fact.
The result is a 0–100 score built from twelve-plus HTML checks, compression detection (gzip, Brotli, zstd), cache policy classification, and those real timing measurements. Here's what the output panel looks like in practice:
The Timing Benchmarks: What Good, OK, and Bad Look Like
Across the 50 URLs I tested, here's how the distribution broke down against the thresholds I use when advising clients. These align broadly with Chrome's field data guidelines but are tightened slightly for professional auditing work.
| Phase | Good | OK | Slow / Investigate | What to Do When Slow |
|---|---|---|---|---|
| DNS | < 20ms | 20–80ms | > 80ms | Switch to a faster DNS provider (Cloudflare, AWS Route 53). Check TTL — low TTLs force repeated lookups. |
| TCP Connect | < 30ms | 30–100ms | > 100ms | Origin is geographically far from the test server. Use a CDN or move compute closer to your largest user region. |
| TLS Handshake | < 80ms | 80–200ms | > 200ms | Enable TLS 1.3 (reduces round-trips). Confirm HTTP/2 is active. Enable OCSP stapling to avoid revocation round-trips. |
| TTFB | < 200ms | 200–600ms | > 600ms | Server-side problem. Check object cache, database query time, PHP/Node worker availability. Not a frontend fix. |
| Download | < 150ms | 150–400ms | > 400ms | HTML document is too large. Enable compression. Remove unused inline scripts/styles. Target < 50KB initial HTML. |
In my 50-site sample, 34% had TTFB above 600ms — and of those, every single one had compression either disabled or falling back to gzip when Brotli was available at the server. Correlation, not causation, but worth noting.
The Cache Policy Labels Explained
The tool classifies cache behaviour into five distinct labels. This is where I see the most confusion in client audits, especially with Next.js and Vercel-hosted apps.
| Cache Label | What It Means | Typical Header Pattern | What to Do |
|---|---|---|---|
| Immutable | Asset will never change at this URL. Cache forever. | max-age=31536000, immutable |
Ideal for hashed static assets. No action needed. |
| Long Cache | Cached for > 1 hour. Good for stable resources. | max-age=86400 |
Good. Ensure your deploy pipeline busts these URLs on update. |
| Short Cache | Cached for < 1 hour. Frequent revalidation. | max-age=300 |
Fine for personalised or frequently updated pages. Review if used on static content. |
| ISR | Next.js Incremental Static Regeneration. CDN serves stale while revalidating in background. | max-age=0, must-revalidate, s-maxage=31536000 |
This is intentional. Do not "fix" it. The CDN edge handles freshness. See callout below. |
| No Cache | Every request hits origin. No caching at any layer. | no-store or absent header |
Investigate. Add appropriate cache headers. Even short caching (60s) dramatically reduces origin load. |
Cache-Control: max-age=0, must-revalidate, I nearly flagged it as a caching failure. It isn't. Next.js ISR deliberately sets max-age=0 for the browser while setting s-maxage for CDN edge nodes. The CDN serves a stale cached copy while a background regeneration request runs. The Page Speed Inspector is one of very few free tools that correctly identifies this pattern and labels it "ISR" rather than "No Cache" — which would be a false alarm and cause unnecessary work.
HTTP/2 Detection: Why the ALPN Probe Matters
Here's something that tripped up a client running Nginx behind a load balancer: their application headers were reporting HTTP/2 via X-Forwarded-Proto, but the actual TLS negotiation was completing over HTTP/1.1 because ALPN wasn't configured on the upstream listener. Every other speed tool I tried reported HTTP/2 as "active" based on the headers. The Page Speed Inspector's separate ALPN probe caught the discrepancy and flagged the mismatch correctly.
This matters because HTTP/2 multiplexing reduces the latency impact of multiple concurrent resource requests. If you think you have it but don't, you're leaving a meaningful performance gain on the table — particularly on pages with many above-the-fold resources.
How It Compares to Other Tools
I use several tools depending on the job. Here's an honest comparison of where the Page Speed Inspector fits versus tools I reach for regularly:
| Feature | ByteWaveNetwork Page Speed Inspector | Google PageSpeed Insights | GTmetrix | Screaming Frog (with PSI integration) |
|---|---|---|---|---|
| Real server-side timing | ✅ Yes | ❌ Lab simulation | ⚠️ Lab + partial real | ⚠️ Via PSI API (lab) |
| HTTP/2 ALPN probe | ✅ Dedicated probe | ❌ No | ❌ No | ❌ No |
| ISR cache detection | ✅ Labelled correctly | ❌ No cache classification | ❌ No | ❌ No |
| Compression detection | ✅ gzip / br / zstd | ⚠️ Reported in opportunities | ✅ Yes | ⚠️ Basic |
| Render-blocking count | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Via Lighthouse |
| Cost | ✅ Free | ✅ Free | ⚠️ Free tier limited | ❌ Paid licence |
| Bulk URL support | ❌ Single URL | ❌ Single URL | ⚠️ Paid feature | ✅ Full crawl |
Screaming Frog remains my go-to for full-site crawls and bulk auditing. But for a fast, protocol-accurate read on a single URL — especially when a client calls me with a "why is this page slow" question — the Page Speed Inspector gives me signal I can't get from a lab tool in under ten seconds.
The Render-Blocking Nuance Nobody Talks About
The tool reports a count of render-blocking resources. When I see this number, my first question is always: where are they, not how many are there?
A render-blocking <script> in your <head> that loads a third-party analytics library before any visible content? Critical to fix. A render-blocking stylesheet reference at the bottom of a long-scroll landing page that only affects content 3,000px below the fold? Technically flagged, practically irrelevant for LCP.
The Page Speed Inspector surfaces the count and lets you investigate — but the judgement call on whether it matters for that specific page's above-the-fold experience is still yours to make. That's the right division of labour between a tool and a practitioner.
TLS and the Hidden 100–300ms Tax
When I migrated a 10,000-page e-commerce catalogue from HTTP to HTTPS several years ago, the first thing we measured post-migration was the TLS overhead. On a cold connection with TLS 1.2, we were seeing 220–280ms added per first-visit session just from the handshake. Moving to TLS 1.3 (which reduces the handshake from two round-trips to one) brought that down to 80–110ms. Enabling session resumption on the load balancer brought repeat-visit TLS time to near-zero.
The Page Speed Inspector shows you the raw TLS timing. If you see > 200ms here, the first things I'd check are: TLS version (is 1.3 enabled?), OCSP stapling (is it active, to avoid the certificate revocation round-trip?), and whether HTTP/2 is actually negotiated (multiplexing amortises the handshake cost across subsequent requests).
Quick Wins Checklist: Run This After Every Audit
After running the Page Speed Inspector, here's the checklist I work through with every result. These are ordered by impact-to-effort ratio based on what I've seen across those 50 sites.
- TTFB > 600ms? Stop all frontend work. Check server object cache, database slow query log, and PHP/Node worker saturation first.
- Compression missing or gzip-only? Enable Brotli at the CDN or web server layer. Brotli typically reduces HTML/CSS/JS by an additional 15–25% versus gzip.
- HTTP/2 not detected by ALPN probe? Verify ALPN is configured on your TLS listener, not just your application layer. Confirm with the inspector after fixing.
- No-Cache label on a public page? Add at minimum
Cache-Control: public, max-age=60. Even 60 seconds of edge caching dramatically reduces origin hit rate under traffic spikes. - TLS > 200ms? Confirm TLS 1.3 is enabled. Enable OCSP stapling. Check whether session resumption is configured on the load balancer.
- DNS > 80ms? Review DNS provider and check your zone's TTL. A TTL of 3600s is reasonable for stable production records; very low TTLs (60s or less) cause repeated cold lookups.
- Render-blocking resources flagged? Locate them in the source. Only action those in the
<head>or early<body>that affect above-the-fold content. Adddeferorasyncwhere appropriate. - Missing meta description? Write one under 160 characters. It won't fix speed but it's a 30-second fix that the tool surfaces and improves CTR.
- Score below 50? Re-run after each fix. The score is cumulative — address TTFB first, then compression, then cache headers. Watch the number move with each change.
- ISR label on a Next.js page? Verify it intentionally. If unexpected, check your
getStaticPropsrevalidate config. If expected, document it so future auditors don't raise a false alarm.
What the Score Doesn't Tell You
The 0–100 score is a useful compass, not a destination. A score of 85 on a page with a 900ms TTFB is technically possible if most HTML checks pass — but that page is still slower than a score-60 page with a 180ms TTFB. I always look at the raw timing numbers first and treat the score as a secondary signal for tracking improvement over time.
Similarly, the tool audits a single URL at a point in time. Server load, CDN cold starts, and geographic routing all affect results. For production monitoring, I run three consecutive checks on the same URL and take the median TTFB as the working number.
Final Thought: Measure at the Protocol Level First
The WooCommerce store I mentioned at the start had perfectly optimised images, deferred scripts, and a respectable Lighthouse score. None of that mattered because the server was haemorrhaging a second on every TTFB. The tools we use shape the fixes we find — and a tool that only shows you frontend rendering metrics will only surface frontend fixes.
Protocol-level measurement — DNS, TCP, TLS, TTFB, download — is where performance audits should start, not end. And now there's a free tool that does it in under ten seconds.
Try Page Speed Inspector — Free
Run a real server-side timing audit on any URL. Get DNS, TCP, TLS, TTFB, compression, cache policy, HTTP/2 detection, and 12+ HTML checks in one report — no sign-up required.
Audit Your URL Now →Disclosure: ByteWaveNetwork is the publisher of the Page Speed Inspector tool referenced throughout this article. This post was written to demonstrate the tool's capabilities using real audit findings. No third-party affiliate relationships exist in connection with this content. Links to competitor tools are editorial references only — no sponsorship or commercial relationship with Screaming Frog, GTmetrix, or Google is implied or exists.
Newsletter
Enjoyed this guide? Get more in your inbox — free
New guides published twice a week, based on real crawl data. No spam.