I work on OnePassApps, so this is our own site, and every number below was measured on it today - 8 November 2026 - with plain HTTPS requests from outside the browser, no session, no cookies, no JavaScript.
We have already written about what our server sends back: the response headers of every page and which of our URLs can revalidate and which cannot. This one is about a header that was missing from both lists: server-timing. It is not in the HTML, it is not in the page, and it is the only thing our server sends that says where the time went.
The header, and the shape it comes in
Every response carries it in the same two-metric form:
server-timing: cfEdge;dur=13,cfOrigin;dur=31
Cloudflare splits its own handling of the request into two spans and labels them cfEdge and cfOrigin, each with a duration in milliseconds. Cloudflare does not publish what it counts inside each span, so read them as the two halves it reports - not as a promise about what our own server was doing.
We fetched all 56 URLs in our sitemap.xml. Every one answers HTTP 200. All 56 carry the header. Not one page in the fleet omits it, and the shape is identical on every one: two metrics, two durations, comma-separated.
The values are not a constant. Across the 56 pages there are 52 distinct header values - four pairs of pages happened to report the same numbers - and 18 distinct cfEdge values and 21 distinct cfOrigin values.
Where the time actually goes
Here is the whole fleet, read off the header:
cfEdge |
cfOrigin |
edge + origin | |
|---|---|---|---|
| range | 2 - 27 ms | 11 - 46 ms | 13 - 71 ms |
| mean | 13.0 ms | 31.6 ms | 44.6 ms |
The origin half is the bigger one. Across all 56 responses the origin accounts for 70.9% of the reported time and the edge for 29.1%. On 40 of the 56 pages the origin took at least twice as long as the edge. On three pages it took less: /studios/files (21 ms edge, 13 ms origin), /apps/newsflow (17 / 13) and /guides/email-signature (14 / 13).
Page size predicts nothing
The obvious guess is that the big pages are the slow ones. The measurement says no.
The correlation between a page's byte size and its cfOrigin duration across the 56 pages is 0.056 - essentially zero. The three pages that show this most clearly:
| Page | Bytes | edge | origin | total |
|---|---|---|---|---|
/terms |
75,113 | 8 ms | 32 ms | 40 ms |
/guides/word-counter |
30,103 | 25 ms | 46 ms | 71 ms |
/apps/ambient-noise-mixer |
19,253 | 2 ms | 11 ms | 13 ms |
Our largest page, /terms at 75,113 bytes, is not our slowest - it reports 40 ms in total. Our slowest page, /guides/word-counter, is less than half its size and takes 71 ms. And the fastest page in the fleet, /apps/ambient-noise-mixer at 19,253 bytes, answers in a reported 13 ms.
The fleet groups tell the same story. The 22 app pages average 19,350 bytes and 42.4 ms of reported time. The 7 studio pages are smaller (17,392 bytes) and take longer (47.9 ms). The 23 guide pages are the biggest (30,510 bytes) and land in between at 45.4 ms. Size does not order these groups; something else does.
The number moves, the page does not
We fetched the same three URLs three times each, in the same script, seconds apart. The byte counts were identical every time. The header values were not:
| URL | bytes (all runs) |
cfOrigin across three runs |
|---|---|---|
/ |
25,158 | 28 ms, 42 ms, 31 ms |
/apps/newsflow |
19,132 | 32 ms, 17 ms, 45 ms |
/terms |
75,113 | 35 ms, 31 ms, 17 ms |
The same bytes, a different number every time. That is the header doing its job - it is a measurement of one request, not a property of a page. It also means a single curl of one URL tells you about one request and nothing else.
It is on the edges of the site too
- The 404 miss document carries it:
cfEdge;dur=17,cfOrigin;dur=35, 14,320 bytes,cache-control: no-store. The page that does not exist still reports where its time went. - The trailing-slash 308 carries it:
cfEdge;dur=17,cfOrigin;dur=21, withcontent-length: 0. A redirect that sends no body still bills its two spans. - The API host carries it too, and in the other order:
GET /api/healthonapi.onepassapps.comanswerscfEdge;dur=28,cfOrigin;dur=23- 410 bytes,cache-control: private, no-store, max-age=0. There the edge half is the larger one.
What it does not cover
The header reports 44.6 ms on average. The wall-clock time around the same 56 requests averaged 69.6 ms - about 1.56 times as long. The difference is everything outside those two spans: TLS, the round trip, and the transfer of the body itself. So server-timing is a breakdown of the server-side handling, not a stopwatch for the request.
A caveat worth stating: it depends on the request
This header is not returned to every client. The requests that carried it were the ones that did not send an Accept header; curl with its default headers (which include Accept: */*) got no server-timing at all - 0 of 5 over HTTP/2 and 0 of 5 over HTTP/1.1 - while the same URL over HTTP/1.1 with the Accept header removed carried it on 4 of 4 requests. We did not isolate the exact trigger beyond that, and we are not claiming to know Cloudflare's rule.
There is a second variation: the metric inside the header is not always the same pair. Most requests carried the cfEdge/cfOrigin split, but in two of our probes the header carried cfCacheStatus;desc="DYNAMIC" instead - and one of those two used the same request shape that returned the split on other runs. So even when the header is present, what it says depends on the request.
The honest limits
- One build, one day (8 November 2026), one network, one Cloudflare edge, plain HTTPS from outside the browser.
- These are the durations Cloudflare reports for its own handling. It does not document what each span includes, so we are not attributing them to our own application server.
- One fetch per URL for the fleet table, and three per URL for the repeat table. A single sample per page is a sample.
- No signed-in session, so no claim about headers that might differ behind a sign-in.
- The
Accept-header dependence was observed but not explained. We did not test whether a browser sees it.
Why it is worth reading
Two of our earlier posts were about headers that describe policy - what the browser may cache, what code may run. This one describes cost: which half of the request is expensive, and that the half we would have guessed at (the size of the page) is not the half that varies. The edge is a fairly flat 13 ms across the fleet. The origin is where the spread is, from 11 ms to 46 ms, and nothing about the page's byte size predicts where it lands.
If you want to see it yourself, run curl -sI -H 'Accept:' https://app.onepassapps.com/ and read the server-timing line - then run it again and watch the numbers change while the bytes do not. Or open the Ambient Noise Mixer, the fastest page in the fleet, and let it run in your browser; the app guides explain what each tool does with the file you give it.
I work on OnePassApps, so this is our own site and our own build - the numbers above are measurements we took and can repeat, not estimates.
Top comments (0)