Between the click on a link and the first byte of HTML, plenty happens on the server: routing, session handling, database queries, template rendering, often a call to an inventory or pricing system on top. The browser waits during that window - and it waits idle. Without markup it knows neither the LCP image nor the critical stylesheet, and it has not even opened connections to the third-party origins involved. In the field this wait is not an edge case: only 44 percent (HTTP Archive Web Almanac 2025) of mobile sites reach a good TTFB below 0.8 seconds, 40 percent sit in the middle band and 17 percent are rated poor (HTTP Archive Web Almanac 2025). The informational status code 103 from RFC 8297 closes exactly this gap: while still computing, the server sends Link headers carrying preconnect and preload hints, and the browser starts working before the final response even exists (IETF RFC 8297). This article shows what 103 actually delivers, how it differs from resource hints in the HTML head and from lowering TTFB itself, how the rollout looks at web server and proxy level - and where the limits run.
Key takeaways
- The informational status code 103 from RFC 8297, published in December 2017, sends Link headers with preconnect and preload hints while the server is still working, so the browser opens connections and fetches critical files before the first HTML byte exists.
- Early Hints does not shave a single millisecond off TTFB; it only fills the waiting time. If the server can send the final response immediately, regular hints in the main response work better, and below roughly 200 milliseconds of think time the effort rarely pays off.
- Good candidates are render-blocking resources and the LCP element: the critical stylesheet, a web font with crossorigin, the hero image and preconnect to third-party origins. Four to six entries are enough, and prefetch is not supported over 103 (Chrome for Developers).
- nginx has passed 103 responses from proxy backends through since version 1.29.0 of 24 June 2025, using the early_hints directive (nginx Changelog). The hints themselves come from the application or from a per-URL-pattern profile on the reverse proxy.
- On a full-page cache hit there is almost no think time left to fill. The payoff lies with responses that cannot be cached: personalised home pages, logged-in states, cart and checkout steps, and faceted search results.
- Safari does not act on preload via 103, cross-origin redirects discard the hints, and browsers only process the first 103 response (MDN Web Docs). Proving the effect requires field data over at least 28 days before and after activation.
The quiet time between request and first byte
A waterfall chart makes the problem visible in seconds. The first bar belongs to the navigation request, and on dynamic pages it is often the longest: the connection is open, the request is out, and after that nothing moves on the wire. The server is still assembling the document. As long as no markup exists, the browser can discover nothing - no stylesheet, no font, no hero image. The preload scanner, otherwise so reliable at reading ahead, needs bytes to read, and there are none yet. In the waterfall this phase is an empty strip.
That strip carries weight in the field. 55 percent (HTTP Archive Web Almanac 2025) of desktop sites and 44 percent (HTTP Archive Web Almanac 2025) of mobile sites reach a good TTFB below 0.8 seconds; 12 and 17 percent respectively sit above the 1.8 second threshold and count as poor (HTTP Archive Web Almanac 2025). Largest Contentful Paint shows a similar spread: 74 percent of desktop pages but only 62 percent (HTTP Archive Web Almanac 2025) of mobile pages achieve a good score, and the share of poor experiences on mobile is nearly double at 13 versus 7 percent (HTTP Archive Web Almanac 2025). Because LCP is the sum of several sequential phases - TTFB, resource load delay, resource load duration and element render delay (HTTP Archive Web Almanac 2025) - every millisecond of server think time flows straight into the metric.
The obvious answer is: lower the server response time. That remains the correct first step, and the article on lowering server response time in detail walks through the usual levers from query profiling to object caching. Yet think time rarely drops to zero. A product page with live availability, a personalised basket, a faceted search result: such responses cost compute time that can be reduced but not defined away. This is precisely where Early Hints enters - it makes the remaining think time usable instead of fighting it.
Two questions worth keeping apart
What status code 103 actually does
RFC 8297 was published in December 2017 and defines 103 as an informational status code: it indicates to the client that the server is likely to send a final response with the header fields included in the informational response (IETF RFC 8297). The word informational matters. A 103 response does not end the exchange. It is an interjection on the same connection, followed later by the actual response - typically 200, 301 or 404. The client may use the hints but has to expect the final response to differ.
The payload sits in the Link header. Two relation types matter in practice: preconnect opens the connection to an origin, meaning DNS resolution, TCP handshake and TLS negotiation, while preload starts the download of a specific file (MDN Web Docs). For third-party origins two separate preconnect entries are required when both CORS-free and CORS-protected resources come from the same host - images and fonts, for instance - because the connections are not interchangeable (MDN Web Docs). A Content-Security-Policy header may also appear in the early hint response; it is enforced while the hints are processed and can be overridden by the final response (MDN Web Docs).
GET /product/running-shoe-x HTTP/2
Host: www.example.com
# Server has accepted the request and is still computing:
HTTP/2 103
Link: </assets/critical.css>; rel=preload; as=style
Link: </img/hero-1600.avif>; rel=preload; as=image
Link: <https://assets.example.com>; rel=preconnect
Link: <https://assets.example.com>; rel=preconnect; crossorigin
# ... 350 ms later, rendering has finished:
HTTP/2 200
Content-Type: text/html; charset=utf-8
Link: </assets/critical.css>; rel=preload; as=styleThe browser can use those hints to warm up connections and request subresources while waiting for the main resource (Chrome for Developers). Files fetched via preload are stored in the HTTP cache and retrieved from there by the page later (Chrome for Developers). That is why the effect is no trick but plain parallelisation: the same work happens earlier.
Rules worth knowing from the specification
Drawing the line: head hints and TTFB work
The most common question in a project is: we already have preload in the head - why add 103? The answer is timing. A resource hint in the HTML head can act at the earliest once the browser has parsed the head, and for that it needs the first byte plus a few packets. How these classic hints work and where they make sense is covered in the article on resource hints with preload and prefetch. Early Hints moves the same impulse forward - ahead of the first byte of the final response.
Equally important is the second distinction: Early Hints does not lower TTFB. Server think time stays exactly as long as it was; only its knock-on effect on downstream resources shrinks. A site with a 1.8 second response time still has it afterwards - LCP can still arrive earlier because the stylesheet and image are already cached when the HTML lands. Conversely: if the server can send the final response right away, Early Hints is not useful, and regular hints on the main response are the better choice (Chrome for Developers).
The third confusion concerns the transport layer. HTTP/3 and QUIC shorten connection setup but change nothing about the time an application needs to render; the differences are broken down in the article on HTTP/3 and QUIC in practice. Early Hints works on a different axis - it fills waiting time instead of shortening it.
| Technique | Takes effect | What it delivers | What it does not deliver |
|---|---|---|---|
| Early Hints 103 | during server think time | connection setup and downloads of critical files before the first byte | does not lower TTFB, applies to navigation requests only |
| preload/preconnect in the head | after the first byte | prioritizing discovered and undiscovered resources in the document | cannot use the think time preceding it |
| TTFB optimization | before the response | shorter think time through caching, query and application work | has limits on personalised and dynamic responses |
| Full-page cache | on a cache hit | response without an application run, TTFB in the low tens of milliseconds | does not apply to personalised or non-cacheable pages |
Which resources are candidates
The practical recommendation is narrow: hint render-blocking subresources such as synchronous JavaScript, stylesheets or web fonts, plus the resources that contribute most to LCP and First Contentful Paint (Chrome for Developers). Notably, the guidance adds that what you decide to hint via Early Hints may differ from what you traditionally preconnect or preload in your HTML (Chrome for Developers): what you kick off before the first byte follows different rules from what you prioritize inside the document.
The LCP image
The hero or product image is the LCP element on 85.3 percent of desktop pages and 76 percent of mobile pages (HTTP Archive Web Almanac 2025). A preload with as=image before the first byte saves the window the preload scanner would otherwise open only after HTML parsing.
The critical stylesheet
Render-blocking CSS holds back the first frame. Anyone already working with critical CSS above the fold knows the file; it is stable, small and therefore an ideal candidate for as=style.
The web font
Fonts are discovered late because they are requested only after CSS evaluation. A preload with as=font and crossorigin shortens that chain. How loading strategy and font-display interact is shown in the article on web font performance.
The third-party origin
Asset host, media domain or image service: every additional origin costs DNS, TCP and TLS. A preconnect handles that during think time. CORS-protected and CORS-free resources need two separate entries (MDN Web Docs).
The negative list matters just as much. prefetch does not work through Early Hints - only preconnect and preload are supported (Chrome for Developers). And resources that are not cacheable, or whose URL changes frequently, do not belong in the header: with versioned filenames such as main.fa231e9c.css a double fetch looms when the hint still points at the previous version (Chrome for Developers). Anyone already steering priorities via fetchpriority and priority hints should keep both lists consistent instead of maintaining two truths.
- Four to six hints at most - each additional one competes for the same bandwidth
- Only resources needed on practically every page of that type
- Prefer stable URLs; hashes that change with every deploy need an automated sync
- Do not hint a file that the document ends up not using - that is paid bandwidth without return
- Decide per page type: home, category, product detail and search results have different critical paths
Rollout in nginx and at the proxy layer
At web server level the path is now clearly documented. Since version 1.29.0, released on 24 June 2025, nginx supports response code 103 from proxy and gRPC backends and ships the early_hints directive for it (nginx changelog). It is available in the http, server and location contexts and defines the conditions under which a 103 response is passed to the client: if at least one parameter is not empty and not 0, the response goes out (nginx documentation). Received 103 responses are passed on as is, without interpretation (nginx documentation).
# Only for real navigations and only over HTTP/2 or HTTP/3
map $http_sec_fetch_mode $early_hints {
navigate $http2$http3;
}
server {
listen 443 ssl;
http2 on;
location / {
early_hints $early_hints;
proxy_pass http://app_backend;
}
}The application remains the source of the hints: it sends the 103 response with its Link headers as soon as it knows which page type is being rendered - and keeps computing afterwards. In PHP the SAPI handles this depending on the setup, in Node or Go the HTTP server does it directly. Where there is no control over application code, the hints can be produced at the reverse proxy or CDN layer by storing a static hint profile per URL pattern. That is less precise but considerably faster to roll out, and often sufficient for shops with clear page types.
- Check the transport: HTTP/2 or later must be in place, otherwise 103 should stay off (IETF RFC 8297)
- Identify page types and define a hint profile per type
- Produce the hints: in the application before the expensive part of processing, or at the proxy per URL pattern
- Enable pass-through: set
early_hintsin the matching location block (nginx documentation) - Verify in the network panel: the 103 response must appear before the 200 and the named resources must start earlier
- Watch field data for at least 28 days before drawing a conclusion
Interaction with the full-page cache
This is where many projects take the wrong turn. When a page is served from the full-page cache, the reverse proxy delivers it within a few milliseconds - there simply is no think time to fill. On a cache hit Early Hints therefore adds little, and the effort of generating and maintaining headers is out of proportion. How cache layers can be stacked sensibly is described in the article on caching strategies with Varnish and Redis.
The value sits with non-cacheable responses
Between the two worlds sits a practical special case: a cache miss on a page that is cacheable in principle. Full think time occurs there too, and 103 helps. In practice it pays to tie the hints to cache status rather than hard-coding them per route. The value of a technical server analysis rises sharply once cache hit rate and think time per page type are available separately.
The honest limits
Early Hints is progress for part of the traffic, not a cure-all. That starts with browser support: preconnect via Early Hints is processed from Chrome and Edge 103, Firefox 120 and Safari 17; preload from Chrome and Edge 103 and Firefox 123, but not in Safari (Chrome for Developers). Anyone aiming primarily at preloading the LCP image therefore reaches a mostly Chromium- and Firefox-shaped share of the audience - for the rest the page stays as fast as before, just not faster.
- Transport: sending 103 over HTTP/1.1 is discouraged unless the client is known to handle informational responses correctly - a client that mistakes them for a final response can misattribute all subsequent responses on the same connection (IETF RFC 8297)
- First response only: a server may send multiple 103 responses, but browsers process only the first (MDN Web Docs)
- Cross-origin redirect: if the navigation ends on a different origin after a redirect, the hints are discarded (MDN Web Docs)
- Navigations only: the mechanism does not apply to subresources, XHR or fetch calls (Chrome for Developers)
- No prefetch: anticipatory loading of the next page belongs in speculation rules for instant navigation, not in the 103 header (Chrome for Developers)
- Adoption: field usage is low and exceeds 6 percent only in the top one million group on desktop; in the other rank groups it mostly stays below 5 percent (HTTP Archive Web Almanac 2025)
For compatibility and security reasons, it is recommended to only send HTTP 103 Early Hints responses over HTTP/2 or later unless the client is known to handle informational responses correctly.
The trend does point upwards, though: over the past three years usage has climbed from just over 1 percent to roughly 4 percent (HTTP Archive Web Almanac 2025). For comparison: fetchpriority="high" now appears on 17 percent of mobile pages with an LCP image, while classic preload for the LCP image sits at only 2.1 to 2.2 percent (HTTP Archive Web Almanac 2025). The toolbox around the early critical path is being used more broadly overall.
Measurement plan: before, after, in the field
An effect that cannot be evidenced is, in case of doubt, no effect. So the starting point is a baseline measurement, not a configuration change. Published measurements from large platform operators cite LCP improvements of several hundred milliseconds; in a comparison under throttled mobile conditions the difference reached up to a second (Chrome for Developers). Such figures are reference points, not a forecast for a specific project - your own think time, your own critical path and your own audience decide.
- Capture the baseline: LCP and TTFB from field data, split by device category and page type, over at least 28 days
- Break down the LCP subparts: TTFB, resource load delay, resource load duration, element render delay - the second is the one Early Hints is meant to shrink
- Add a lab comparison: identical conditions before and after activation, with realistic throttling instead of a fast office line
- Roll out gradually: one page type first, keep a control group, widen only afterwards
- Hunt for double fetches: check in the network panel whether a hinted file loads twice - that would signal wrong cache headers
- Assess after 28 days: pull field data again and compare against the baseline, not against a gut feeling
The difference between lab and field data is not a detail here but the core of the assessment; the underlying method is described in the article on field data versus lab measurements. Two neighbouring topics from this week are worth a look as well: how rendering work in the browser can be saved is shown in the article on content-visibility and skipped rendering work; how strongly a consent dialog can delay LCP is covered in the article on cookie banners and their effect on Core Web Vitals.
When the effort pays off
From our project experience Early Hints is rarely the first topic of an optimization and frequently a sensible fifth. Ahead of it stand the classics: image formats and sizes, render-blocking CSS, third-party script weight, cache layers. Afterwards, though, once think time no longer drops structurally, 103 is one of the few remaining levers that works without touching layout or editorial processes.
Rather worth it
Dynamic, personalised or poorly cacheable pages with think time well above 200 milliseconds, stable critical resources, a predominantly Chromium-based audience.
Hardly worth it
Static pages from the edge cache with a very short TTFB, frequently changing file hashes without automation, offerings with a strongly Safari-leaning audience.
Check first
Setups behind legacy proxies, HTTP/1.1 segments inside the internal network and routes with cross-origin redirects - the benefit may fail to materialise or the effort may rise there.
In practice Early Hints is therefore a typical outcome of a server audit: the analysis shows where think time arises and where it cannot be reduced further; the rollout then happens at web server and proxy level, without rebuilding the frontend. Which further building blocks belong to that picture - from compression through cache layering to the connection level - is summarised in the overview of services around load time and Core Web Vitals. Anyone wanting to tackle server response time directly will find the matching steps on the page about TTFB optimization.
Sources and studies
early_hints directive, version 1.29.0 of 24 June 2025) and the HTTP Archive Web Almanac 2025 (Performance chapter, field distributions for TTFB and LCP). Supplemented by experience from our own server and frontend projects (project experience).preconnect is processed by Chrome and Edge from version 103, Firefox from 120 and Safari from 17; preload by Chrome and Edge from 103 and Firefox from 123, but not by Safari (Chrome for Developers). The benefit therefore varies with the audience, and part of the traffic stays untouched - the page does not get faster there, but it does not get slower either.Related Articles
PHP Runtime Tuning: OPcache, JIT and FPM Workers
Between web server and database sits the PHP runtime. How OPcache, preloading, JIT and FPM workers shape your response time under load, and how to measure it.
Redirect Chains: The Hidden Delay Before the First Byte
Every redirect costs a round trip before the first byte. Learn how to detect HTTP, www and slug chains and reduce them to a single hop without losing SEO value.
Break Down LCP into Four Phases: the Subpart Analysis
Stop optimizing Largest Contentful Paint blindly: measure TTFB, load delay, load time and render delay individually and target the biggest lever deliberately.