Open Chrome devtools → Network → click this request → "Timing" tab. Each entry below shows up as a colored bar under "Server Timing".
This request
| span | duration (ms) |
|---|---|
| db.query | 40.0 |
| cache.get | 15.0 |
| render-prep | 0.0 |
| total | 55.0 |
Verify from curl
curl -sI https://demo.bext.dev/examples/server-timing | grep -i server-timing
Source — src/app/examples/server-timing/page.tsx
// Loader measures a few spans, then returns a raw Response so the
// Server-Timing header is threaded through bext's response pipeline.
// Chrome devtools → Network → this request → "Timing" tab shows each
// span as a labeled colored bar.
export async function loader({ request }: LoaderArgs) {
const t0 = performance.now();
await wait(40); // pretend: db.query
const t1 = performance.now();
await wait(15); // pretend: cache.get
const t2 = performance.now();
// ... build body ...
const t3 = performance.now();
return new Response(body, {
status: 200,
headers: {
"content-type": "text/html; charset=utf-8",
"server-timing": [
`db;dur=${(t1 - t0).toFixed(1)};desc="db.query"`,
`cache;dur=${(t2 - t1).toFixed(1)};desc="cache.get"`,
`render;dur=${(t3 - t2).toFixed(1)};desc="render-prep"`,
`total;dur=${(t3 - t0).toFixed(1)};desc="total"`,
].join(", "),
},
});
}