HTTP 103 Early Hints — Let the Browser Work While Your Server Thinks
HTTP 103 Early Hints — Let the Browser Work While Your Server Thinks
A browser requests a document, but the server may need time before it knows what to return. It might query a database, wait for an upstream service, or render a page through a PHP application. During that interval, the connection can appear idle even though the server is doing useful work. Is there a safe way to give the browser something useful to do before the final response is ready?
HTTP 103 Early Hints is one answer. It lets a server send a preliminary response containing hints about resources that are likely to be needed. A browser may use those hints to start a connection or fetch a stylesheet while it waits for the eventual response. The important words are preliminary and likely: 103 is not the document, and it is not a promise that the hinted resource will be used.
The Gap Before the Final Response
Consider a slow document request. The browser sends GET /dashboard. The application then performs several operations before it can produce HTML. If the stylesheet and a critical script are already known, waiting to mention them until the final response wastes part of that interval.
Early Hints makes the sequence more like this:
GET /dashboard
Host: example.com
HTTP/2 103 Early Hints
Link: </assets/app.css>; rel=preload; as=style
Link: <https://cdn.example.com>; rel=preconnect
HTTP/2 200 OK
Content-Type: text/html
Link: </assets/app.css>; rel=preload; as=style
<!doctype html>
...
The 103 response tells the client what the server expects to send next. The final response still has to arrive, and its headers remain authoritative. According to RFC 8297, a client can evaluate the early fields speculatively, but that evaluation must not change how it processes the final response.
What Can the Browser Do?
The most useful hints are usually Link fields. With rel=preload, the server can identify a resource that is important to the initial page and provide its destination type with as. With rel=preconnect, it can suggest that the browser prepare a connection to another origin.
These are still hints. The browser can decide that a resource is already cached, unsupported, unsafe to fetch in the current situation, or no longer relevant after a redirect. The MDN reference for 103 also notes that browsers impose compatibility restrictions and may discard early work when the final navigation redirects to another origin.
That makes Early Hints different from putting a stylesheet link in the final HTML. The HTML link is discovered after the document arrives. A 103 link can be discovered earlier, during the server's preparation time. It is also different from HTTP/2 server push: Early Hints suggests work and leaves the browser in control of fetching, while server push sent bytes whether or not the browser already had the resource.
When Is It Worth Considering?
Early Hints is not automatically useful for every page. If an application can return its final response immediately, the ordinary Link header or an HTML <link> element may be enough. Google Chrome's implementation guidance frames Early Hints as a way to use server think-time, not as a replacement for basic resource discovery.
The likely candidates have three properties:
- They are needed on important entry pages, such as a homepage or a common landing page.
- They are stable enough that the server can predict their URL before generating the document.
- They are cacheable and genuinely used by the final page.
A hashed asset that changes on every deployment can be a poor candidate if the hint and the generated HTML can disagree. A resource that is rarely used may merely consume bandwidth early. Chrome's documentation specifically warns that a non-cacheable resource can be fetched twice: once because of the early hint and again when the document discovers it.
So the first step should not be adding a header everywhere. Identify a slow navigation, inspect which resources are discovered late, and compare a controlled change against a baseline. Without that measurement, “faster” is only an assumption.
A Conservative NGINX Proxy Pattern
NGINX documents an early_hints directive in its core HTTP module. The directive appeared in NGINX 1.29.0 and controls when a 103 response received from an upstream server is passed to the client. NGINX's example gates the response on HTTP/2 or HTTP/3:
map $http_sec_fetch_mode $early_hints {
navigate $http2$http3;
}
server {
location / {
early_hints $early_hints;
proxy_pass http://application_backend;
}
}
This example does not create a 103 response by itself. The upstream application must send the informational response and its Link fields. NGINX then passes an upstream 103 response as-is when the condition is true. The official NGINX documentation is the authority for the directive's syntax and version requirement.
The navigate check is deliberate. It avoids treating every request for an image, script, or API response as a document navigation. The $http2$http3 expression also keeps the example away from HTTP/1.1 clients unless the server has a specific reason and evidence that those clients handle informational responses correctly.
Why the Final Response Still Matters
It may seem redundant to repeat the Link header in the final response, but the two responses have different jobs. The early response gives the client an opportunity to start useful work. The final response describes the actual representation. If the application changes its mind, the final response can omit or replace a hint.
The HTML Living Standard describes Early Hints as part of the browser's link-processing model. That does not turn a preload into a guarantee. A preload still needs correct destination metadata, appropriate cache behavior, and a final page that uses the resource. A browser may also limit which hints it processes. MDN currently recommends sending 103 over HTTP/2 or later unless the server knows its clients handle informational responses safely.
Limits and Failure Modes
There are several reasons to be cautious:
- It is speculative. A wrong hint spends connection and bandwidth before the server has proved the resource is needed.
- It does not replace authorization or response headers. The final response remains the source of truth.
- Protocol and browser support matter. RFC 8297 warns about clients that mishandle informational responses, especially on HTTP/1.1.
- Redirects can invalidate the work. Cross-origin navigation may cause the browser to discard resources obtained from the early response.
- It needs server think-time. If there is no meaningful gap before the final response, ordinary preload or preconnect is simpler.
These limits are not arguments against the feature. They are a reminder that Early Hints is an optimization layer. It should be introduced after the page's resource graph, caching, protocol negotiation, and measurements are understood.
Conclusion
HTTP 103 Early Hints gives a server a small intermediate vocabulary: “while I prepare the answer, this resource is likely to matter.” The browser may use that time to connect or preload, but it remains free to ignore the hint. The final response still decides what the page is and which headers apply.
For a PHP application behind NGINX, the most defensible starting point is narrow: choose a slow navigation, hint only stable and cacheable resources, keep the hints in the final response too, and gate forwarding to clients and protocols that can handle them. If the measured result is not better, there is no shame in removing the optimization. A smaller, predictable response is often better than a clever hint that guesses wrong.
References
- RFC 8297: An HTTP Status Code for Indicating Hints, Kazuho Oku, IETF, December 2017.
- 103 Early Hints, MDN Web Docs, modified June 22, 2026.
- 103 Early Hints, Kenji Baheux and Barry Pollard, Chrome for Developers, published June 23, 2022, updated July 10, 2026.
- Module ngx_http_core_module: early_hints, NGINX documentation.
- HTML Living Standard: Early hints, WHATWG, updated November 9, 2026.
