SiteTidy
HomeGuidesHTTP 103 Early Hints: Make Server Think Time Useful
Performance

HTTP 103 Early Hints: Make Server Think Time Useful

A practical guide to HTTP 103 Early Hints: when preconnect and preload help, when they double-fetch, how redirects and CSP change the result, and how to roll them out safely.

Published on September 4, 2026

A slow HTML response creates an awkward gap in page loading.

The browser has asked for the document, your application is rendering it, querying a database or waiting on an upstream service, and meanwhile the browser does not yet know that it will shortly need /app.css, a font, or a connection to a CDN.

HTTP 103 Early Hints exists to use some of that gap.

Instead of waiting until the final 200 response is ready, a server or intermediary can send an informational 103 response containing Link hints. The browser can begin a useful connection or resource fetch while the origin is still preparing the document.

That sounds like free performance. It is not. Early Hints are most useful when server think time is material and the critical dependency is predictable before the final response exists. If either part is missing, the optimisation can become noise or, worse, duplicate work.

What actually happens on the wire

A simplified response can look like this:

HTTP/2 103 Early Hints
Link: </assets/app.css>; rel=preload; as=style

HTTP/2 200 OK
Content-Type: text/html; charset=utf-8

<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="/assets/app.css">
  </head>
  ...
</html>

The important detail is that 103 is not the response to the navigation. It is an informational response sent before the final response.

RFC 8297 defines the status specifically so a server can expose hints before it is ready to produce the final header block. MDN describes the same practical use: preconnect to an origin or begin preloading a resource while the server prepares the final response.

That distinction matters operationally. Your application still owes the client its normal 200, 304, redirect or error response. Treating a 103 as though it completes the request is a client or proxy bug, not an Early Hints feature.

The best case is a boring, predictable critical resource

I would start with resources that satisfy three conditions:

  1. They are needed on nearly every response for the route.
  2. Discovering them from the HTML would otherwise happen noticeably later.
  3. Fetching them early is unlikely to be wasted.

A fingerprinted, render-blocking stylesheet is a good example:

Link: </assets/site.8f32c1.css>; rel=preload; as=style

A third-party origin that the page reliably needs may be a better candidate for preconnect:

Link: <https://static.example-cdn.com>; rel=preconnect

The tempting approach is to dump every important asset into the 103. I would do the opposite. Early Hints move requests forward in time; they do not make bandwidth, sockets or server capacity free.

If you preload five resources and only one is genuinely render-critical, you can compete with the resource that actually matters.

preconnect is often the safer first experiment

A preconnect does not commit to downloading a particular asset. It asks the browser to establish the connection work it is likely to need later.

That can include DNS resolution, TCP setup and TLS negotiation depending on the connection state and protocol.

For a stable cross-origin dependency, this is a relatively conservative bet:

HTTP/2 103 Early Hints
Link: <https://cdn.example.com>; rel=preconnect

Cross-origin fonts need extra care. MDN’s example shows that CORS-protected resources can require a connection with the appropriate crossorigin semantics, rather than assuming one generic preconnection covers every request type.

I would use preconnect when I know the origin early but do not yet know the exact resource with enough confidence to preload it.

Preload only resources the final page will really consume

Preload is more aggressive because the browser can fetch the resource immediately.

That makes the cache behaviour important.

Chrome’s Early Hints guidance points out a particularly nasty failure mode: Early-Hinted preloads are placed in the HTTP cache for the page to consume later. If the resource is not cacheable, it can be fetched once because of the Early Hint and then fetched again when the document discovers it.

You have converted an optimisation into a double download.

Before adding a preload, check the final resource response rather than just the HTML:

Cache-Control: public, max-age=31536000, immutable

That policy is appropriate for a content-hashed static asset, not for every resource. The broader point is that the early fetch must be reusable by the final page.

Also make the preload attributes agree with the eventual request. Fonts are the classic example:

Link: </fonts/inter-latin.woff2>; rel=preload; as=font; type="font/woff2"; crossorigin

A mismatch in destination or CORS mode can prevent reuse and cause another fetch.

Early Hints do not rescue a fast origin

Suppose your server produces the final HTML headers in 25 ms. There may simply not be enough time for an Early Hint to create a meaningful head start.

Now suppose a personalised dashboard spends 450 ms assembling data before the HTML response begins. If its critical stylesheet and asset origin are known almost immediately, the browser has hundreds of milliseconds in which it could be doing useful network work.

That is the shape of request where I would investigate 103.

This also explains why blindly enabling Early Hints at a CDN can produce underwhelming results. The feature is exploiting a timing window. Measure whether that window exists on the pages you care about.

Redirects make prediction harder

An Early Hint is based on what you believe the final document will need. A redirect can invalidate that belief.

MDN notes that when the navigation ends in a cross-origin redirect, the browser discards the Early Hints work. Chrome documents the same limitation.

So this is a poor place to speculate:

/old-product
   -> 302 https://new.example/product

If a route frequently redirects according to authentication, locale, experiments or canonicalisation, I would resolve that routing decision before investing heavily in resource hints for it.

CSP still matters before the final response arrives

A useful subtlety is that a 103 response can contain Content-Security-Policy while the browser processes the hint.

For example:

HTTP/2 103 Early Hints
Content-Security-Policy: style-src 'self'
Link: </assets/app.css>; rel=preload; as=style

The final response can still carry its own policy. A resource fetched early is not automatically entitled to be used by the final document.

If your application has a serious CSP, do not design Early Hints as a separate performance layer owned by somebody who never looks at the security headers. The two meet before the HTML is rendered.

SiteTidy’s Content Security Policy guide goes into the policy side in more detail.

Do not send 103 everywhere just because your server can

RFC 8297 calls out compatibility risks around informational responses, particularly for HTTP/1.1 clients that mishandle them.

Current MDN guidance recommends sending 103 Early Hints over HTTP/2 or later unless you know the client handles informational responses correctly. Chrome’s implementation guidance similarly recommends HTTP/2 or HTTP/3 and suggests navigation context as a useful guard when emitting hints.

That leads to a fairly conservative production policy:

Is this a top-level navigation?
        |
        +-- no --> no Early Hint
        |
        +-- yes
             |
             +-- HTTP/2 or HTTP/3? -- no --> normally skip
             |
             +-- yes
                  |
                  +-- known, high-confidence hint? --> send 103

I would rather miss a marginal optimisation than make an old proxy or unusual API client part of a performance experiment it never asked to join.

Browser support is not one simple yes/no

The status code can be supported while individual hint behaviours differ.

Chrome’s documentation currently describes Early Hints support across major browsers but shows different support histories for preconnect and preload. It also documents implementation constraints such as top-level navigation use, cacheability for preloaded resources and limitations around responsive image preload.

That is why I would not write deployment logic based on a sentence like “all modern browsers support 103”.

Test the actual hint you intend to send.

A harmless unsupported hint should leave you with the normal final response and normal resource discovery. That fallback is one of the attractive things about the mechanism, provided your page never depends on the Early Hint for correctness.

Responsive images are a bad place to begin

An image can look like an obvious LCP candidate, so preloading it early sounds sensible.

The problem is that responsive image selection may depend on information that is not useful at the point the HTTP Link header is processed. Chrome specifically documents limitations around imagesrcset, imagesizes and media with Early Hints.

I would first optimise image discovery in the document itself and make sure the browser can identify the real LCP candidate without being obstructed by lazy loading or client-side rendering.

Early Hints should not become a workaround for markup that hides critical resources from the preload scanner.

Where Early Hints sit beside Speculation Rules

Early Hints and the Speculation Rules API solve different timing problems.

Speculation Rules ask the browser to prepare a future document navigation before the user commits to it.

Early Hints operate after a navigation request has already reached the server, but before that server has finished producing the final response.

That gives you a useful mental model:

Before click / probable next page
    -> Speculation Rules

Navigation requested, server still thinking
    -> 103 Early Hints

HTML received and parsed
    -> normal preload scanner / resource discovery

Using one does not make the others redundant.

Measure the head start, not the presence of a 103

Seeing 103 Early Hints in a network trace proves only that somebody sent a status code.

The performance question is whether the hinted connection or resource started early enough to affect the critical path.

In Chrome DevTools, Early-Hinted resources can be identified in the Network panel; Chrome’s documentation notes an Early-hints initiator for preloaded resources. Be careful when testing with Disable cache selected: Early Hints preload reuse relies on the browser cache, so that debugging setting can invalidate the thing you are trying to measure.

I would compare at least:

  • request start time for the hinted resource;
  • when the final HTML response begins;
  • whether the hinted resource is reused rather than fetched twice;
  • LCP and other user-visible timing on the target route;
  • bytes transferred and request counts;
  • behaviour on cold and warm connections.

A synthetic waterfall is excellent for understanding mechanism. Real-user performance data tells you whether the mechanism mattered often enough to keep.

A rollout I would be comfortable shipping

Start with one route that has measurable server think time.

Choose one stable dependency, preferably a same-origin fingerprinted stylesheet or a high-confidence preconnect. Confirm that the final page requests it in the same mode and that a preload is cacheable if you use one.

Then capture before-and-after waterfalls and real-user timings.

Only expand the hint set when you can explain why the next resource belongs there. If the list grows because “these files seem important”, stop. Importance is not the criterion. Being predictably critical during otherwise idle server time is.

That distinction is what keeps Early Hints from turning into another pile of speculative requests.

References

Ready to audit your site?

Put this guide into practice immediately using our free tools.

Browse 180+ Free Tools