A five second delay that appears only when the request comes from a bot.
Next streams metadata to browsers but blocks the entire response for HTML-limited bots; the decision is made by shouldServeStreamingMetadata in app-render.js, and the list it recognises is short: facebookexternalhit, Twitterbot, LinkedInBot, Slackbot, Discordbot, WhatsApp, Bingbot, applebot, DuckDuckBot, yandex and clients whose token starts with Google-. On this site generateMetadata was reading the CMS, and metadata resolves outside the page's Suspense boundary, so the response waited on whatever it awaited. Measured against a CMS that accepts connections and never answers, on the same machine and minutes apart: Twitterbot reached the first byte between 5015.58 and 5025.27 ms before the read was removed, and between 16.42 and 18.76 ms after.
The lesson is not in the numbers
The lesson is not in the numbers but in the fact that an ordinary browser makes the defect invisible. The control group measured 15.20 to 39.13 ms before and 16.15 to 16.33 ms after, and in both branches the closing head tag arrived with the first byte, a difference of 0.01 to 0.03 ms, because Next patches streamed metadata in afterwards. The first attempt read exactly that way and concluded there was nothing wrong. Plain Googlebot sits outside the list too, so it gets its first byte at 10.9 ms and its head 5017 ms later. The fix was small, the site name and description now come from the message bundle rather than the CMS, but the gate had to be structural: putting the read back verbatim turns nine assertions red across six files, while hiding the same read inside a helper module leaves the file that scans the source as text green at eight of eight, and only the behaviour layer catches it, seven assertions across five files.
Tags
- Next.js
- SEO