The other half of the number is how long the server takes to produce the first byte, decided by the rendering mode you chose, often by accident. These four routes were hit with 20 concurrent connections against a single next start process.
| Route | Rendering | TTFB p50 | Throughput |
|---|---|---|---|
| /slow | Prerendered | 2.5 ms | 1305 req/s |
| /live | Dynamic | 4.8 ms | 397 req/s |
| /blocking | 400 ms query | 415.9 ms | 47 req/s |
| /stream | Streamed | 3.2 ms | 48 req/s |
A prerendered route is served from disk and costs almost nothing, so keep routes static unless they need the request: a stray cookies() or headers() call in a shared layout turns every page under it dynamic. Rendering on demand is not expensive in itself - /live still served 397 requests a second - but waiting is, and /blocking puts the whole 400 ms of its query into every user's first byte.
Wrapping that query in <Suspense> moved the first byte to 3.2 ms while throughput stayed near 48 requests a second: the same work still has to happen. Streaming does not make the server faster, it stops the shell from waiting for the slowest query (Streaming with Suspense).