Why doesn’t AI mention your brand? Find out which half is brokenGet a free report
LLMention
Method

TTFB, edge caching and prerendered HTML

Prerendered does not mean cached. The build answer and the runtime answer are different, and TTFB plus a cache-status header shows which one a reader got.

By Alex Xu9 min read

"The page is prerendered" is a statement about the build. It does not say what happens when a request arrives: whether an edge cache has a copy, whether the app runtime serves one, or whether the page is rendered again for every visitor. Those are deployment questions, and they show up in one number — time to first byte — and one header, the cache status.

This article measures both on this site, explains why a prerendered page can still be rendered on every request, and lays out the trade between correctness and TTFB. It also says plainly that TTFB is not a citation signal.

What the numbers mean

  • TTFB — time from the request to the first byte of the response. On a server-rendered page it includes routing, data, rendering and network; on a cached page it is mostly network.
  • Total time — TTFB plus the transfer. For a small HTML page the gap is usually the network, not the server.
  • x-nextjs-cache — the framework’s own cache status. HIT means a stored render was served; MISS means it was rendered.
  • cf-cache-status / Age — the CDN’s view: whether the edge held the response and for how long.

A measurement on this site

On 2026-10-29 I requested four URLs three times each from one network and recorded TTFB and total time. The numbers are network-bound — a reader in another region will see different absolutes — but the shape is the point.

URLTTFB (s, 3 runs)Total (s, 3 runs)
/1.99, 2.40, 1.543.36, 4.42, 2.64
/blog/cache-headers-what-an-auditor-sees/1.96, 0.75, 1.632.80, 5.31, 2.63
/pricing/3.79, 1.98, 1.155.03, 2.84, 1.88
/report/?domain=example.com1.32, 2.70, 0.891.73, 3.04, 1.40

TTFB ranges from roughly 0.75 to 3.8 seconds, and the same URL varies by more than a second between runs. The headers explain part of it: the homepage returns cache-control: public, max-age=0, must-revalidate and x-nextjs-cache: MISS on repeated requests, and the response carries no cf-cache-status or Age. In other words, the edge is not holding the HTML, and the route is rendering rather than serving a stored copy.

Why a prerendered page still renders

There are four separate reasons, and they stack:

  1. Prerendering is a build artifact, not a cache. The HTML exists on disk, but something has to serve it. A Worker response is not automatically cached by the CDN; Cloudflare’s documentation says Worker responses are not cached by default.
  2. The header forbids reuse without revalidation. After the 2026-10-23 incident, HTML is max-age=0, must-revalidate. Every cache must check with the origin before serving; a full HTML response is the cost of that check when no ETag path is available.
  3. The framework cache may be per-isolate. x-nextjs-cache: MISS means the render was not served from the framework’s incremental cache. Without a durable cache behind it, an isolate restart loses it, and the next request renders again.
  4. Some pages are intentionally dynamic. /report/ and /api/ are no-store because they depend on the request; their TTFB is a different question.

The second reason is a deliberate choice and the first and third are deployment properties. That distinction matters: a slow TTFB on this site is not evidence that prerendering failed. It is evidence that the deployment chose correctness over edge caching, and that the durable cache is not doing what a static host would do for free.

The options, and what each costs

OptionEffectCost / risk
Accept revalidationEvery HTML view checks with the origin; correctness is preserved.A round trip and a render when there is no usable ETag; slower TTFB.
Edge-cache HTML with a short TTL and purge on deployMost requests are served at the edge.A staleness window after deploy if the purge misses; needs a cache rule that respects the decision.
Durable incremental cache + on-demand revalidationStore renders across isolates, invalidate on content change.More moving parts: a cache binding, a revalidation path, a failure mode when the store is unreachable.
Paid Workers CPURemoves the cold-start CPU ceiling.A monthly cost; does not change the render-per-request logic.

This site has chosen the first option and paid for it in TTFB. The choice is defensible for a product whose claim is that the published version is the running version; it would be the wrong choice for a marketing site whose pages change monthly and whose readers are far from the origin.

How to measure your own

# 1. TTFB and total, three times, for one URL
for i in 1 2 3; do
  curl -sS -o /dev/null -w "%{time_starttransfer} %{time_total} %{http_code}\n" \
    https://your-domain.com/page/
done

# 2. What does the response say about caching?
curl -sS -D - -o /dev/null https://your-domain.com/page/ \
  | grep -iE 'cache-control|age|etag|cf-cache-status|x-nextjs-cache'

# 3. The same page, fetched from a cache-busting hostname or region if available
#    (a different network is the cheapest approximation)

The second command is the one that turns a raw number into an explanation. A slow TTFB with x-nextjs-cache: HIT is a network problem; a slow TTFB with MISS and no edge status is a render problem. They have different fixes.

What TTFB is not

It is not a GEO score. No engine has published a TTFB threshold for citation, and a fast page with no extractable content is not more citable than a slower one that answers the question. It is a delivery dimension: it affects readers and can affect whether a crawler waits for the response at all.

The honest summary is the one the numbers support: prerendered does not mean cached, and "the page exists at build time" does not answer "what did the request receive". Measure the response, name the trade, and do not let a build-time claim stand in for a runtime fact.

Questions about TTFB and prerendering

If a page is prerendered, why does every request still render it?

Prerendering happens at build time; serving it from a cache happens at request time, and those are separate. A Worker response is not cached by the CDN automatically, and a max-age=0, must-revalidate header tells caches to revalidate. The observed x-nextjs-cache: MISS on repeated requests says the route is being rendered rather than served from a persistent cache.

Is a higher TTFB a GEO problem?

Not directly. It is a delivery problem: slower responses cost user experience and can hit crawler timeouts, but no engine has published a TTFB threshold for citation. Treat it as part of the delivery dimension, not a ranking switch.

Should I cache HTML at the edge to fix it?

Only with an explicit staleness policy. If the cache rule ignores the origin's max-age=0, the site can serve a page older than the deploy, which is the incident this site already had. A short TTL plus purge-on-deploy is a trade, not a free win.

Evidence and sources

GEO can boost visibility by up to 40% overall in generative engine responses, and in the paper's Table 1 the best of the tested methods improve on the no-optimization baseline by 41% and 28%. — Generative Engine Optimization, KDD 2024

Every figure in this piece comes from the published study or from the rule set the scanner executes; both are linked, and both can be re-run.

Primary sources

Alex Xu — Maintainer, LLMention

I build and maintain LLMention: the scanner, the rule set and the study behind it. The work is published as source, so the method can be checked rather than taken on trust.

How this site is written and funded →

Read next