103 Early Hints
An informational response that lets the server push resource hints to the client before the final response is ready.
Quick Reference
| Category | 1xx Informational |
|---|---|
| RFC | RFC 8297 |
| Has body | No |
| Cacheable | No |
| Primary use | Preload/preconnect hints while server processes the request |
What 103 Early Hints Means
HTTP 103 Early Hints (RFC 8297) is a 1xx informational response that a server sends before the final response. It carries Link headers with preload or preconnect directives, allowing the browser to start fetching critical subresources — stylesheets, fonts, scripts — while the server is still generating the main response.
The performance problem it solves is the idle browser gap. When a browser requests a page, there is a window of time between when the request arrives at the server and when the server finishes building the HTML (database queries, template rendering, API calls). During that window, the browser is waiting and the network is idle. 103 lets the server say “I’m still working, but I already know you’ll need these resources — start fetching them now.”
103 is distinct from HTTP/2 Server Push. Server Push proactively sends the full resource content. 103 only sends a hint; the browser decides whether to fetch the resource and how to handle it. This makes 103 safer (no wasted pushes for cached resources) and simpler to implement.
How the Timing Works
Without 103, the sequence is: browser sends request → server processes (100–500ms) → server sends full response with Link headers → browser parses HTML → browser fetches subresources. All subresource fetches begin after the full response arrives.
With 103, the sequence is: browser sends request → server sends 103 with Link preload hints immediately → browser starts fetching subresources in parallel → server finishes processing → server sends 200 with full HTML. Subresource fetches overlap with server processing time.
In practice this can save 100–300ms on a cold load, depending on how long the server takes to generate the response and how many critical subresources need to be fetched.
Wire Format
A 103 response looks exactly like a regular HTTP response but with a 1xx status and only headers:
HTTP/1.1 103 Early Hints
Link: </styles/main.css>; rel=preload; as=style
Link: </fonts/inter.woff2>; rel=preload; as=font; crossorigin
Link: <https://cdn.example.com>; rel=preconnect
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Link: </styles/main.css>; rel=preload; as=style
<!DOCTYPE html>...
The final 200 can repeat the Link headers from the 103. This is recommended because some intermediaries may strip 1xx responses, and the final response Link headers ensure the hints reach clients that missed the 103.
103 is only useful over HTTP/2 or HTTP/3. HTTP/1.1 has a limitation: a client that has not opted in to receiving 1xx responses may be confused by an early response. In practice, all modern browsers support 103 on HTTP/2 and HTTP/3 connections.
Server Configuration
nginx (1.25.1+)
location / {
# Send early hints for critical resources
add_header Link "</styles/main.css>; rel=preload; as=style" always;
http2_push_preload on;
# Or use the early_hints directive (nginx Plus / patches)
# early_hints "Link: </styles/main.css>; rel=preload; as=style";
proxy_pass http://app_backend;
}
Caddy (v2.6+)
example.com {
handle /app/* {
reverse_proxy localhost:3000 {
header_up Early-Hints "Link: </styles/main.css>; rel=preload; as=style"
}
}
}
Node.js / Express
app.get('/', async (req, res) => {
// Send 103 immediately
res.writeEarlyHints({
'link': [
'</styles/main.css>; rel=preload; as=style',
'</scripts/app.js>; rel=preload; as=script',
]
});
// Now do the slow work
const data = await db.query('SELECT ...');
const html = renderTemplate(data);
res.send(html);
});
Node.js added res.writeEarlyHints() in version 18.11.0. It sends a 103 response and returns immediately, allowing the rest of the handler to proceed.
Cloudflare Workers
export default {
async fetch(request) {
// Create early hints response
const earlyHints = new Response(null, {
status: 103,
headers: {
'Link': '</styles/main.css>; rel=preload; as=style'
}
});
// In Workers, use waitUntil or structured streaming
// Cloudflare's cache supports 103 pass-through natively
return fetch(request);
}
}
Cloudflare CDN has native support for passing 103 responses from origin servers to browsers. Enabling Early Hints in the Cloudflare dashboard allows Cloudflare to cache and serve 103 responses from edge nodes without the hint needing to travel to the origin.
What to Include in 103 Hints
The most effective hints are for render-blocking resources: CSS files in the <head>, critical fonts, and above-the-fold JavaScript. Hinting for resources that the browser would find quickly anyway (resources referenced early in the HTML) provides minimal benefit. Hinting for resources loaded lazily or conditionally may waste bandwidth if those resources are never needed.
For preconnect, target third-party origins that will be used for critical resources: CDN domains, font providers, API hosts. Establishing a TCP+TLS connection early saves 100–300ms per origin on the first request to that origin.
103 vs Related Mechanisms
| Mechanism | How it works | Risk |
|---|---|---|
| 103 Early Hints | Server sends 103 with Link headers; browser fetches | Low — browser controls fetch |
| HTTP/2 Server Push | Server pushes full resource frames proactively | Medium — can push cached resources |
| HTML preload link | <link rel=preload> in the HTML head | Low — but requires HTML to arrive first |
| Link header on 200 | Preload hints in final response headers | Low — but no timing benefit vs HTML links |
Frequently Asked Questions
Does 103 work with HTTP/1.1?
Technically it can be sent, but HTTP/1.1 clients that are not 103-aware may treat it as an error or ignore it. In practice, 103 is only beneficial and safe on HTTP/2 and HTTP/3 connections. Modern browsers support 103 on these protocols.
Can a CDN cache and serve 103 responses?
Cloudflare supports caching and serving 103 responses from edge nodes natively since 2022. This means the 103 is served from the CDN rather than the origin, giving the timing benefit even when the request is cache-served. Other CDNs have varying support.
What if the final response contradicts the 103 hints?
The browser may have already started fetching the hinted resources. If the final HTML does not reference a hinted resource, the fetch was wasted. This is a correctness risk: keep 103 hints aligned with what the final response will reference. If the final response cannot be predicted (A/B tests, personalization), be conservative with hints.
Is 103 the same as 100 Continue?
No. 100 Continue is part of the request pipeline — it authorizes the client to send a large request body. 103 Early Hints is part of the response pipeline — it delivers resource hints to the client before the full response is ready. They are unrelated beyond both being 1xx informational codes.