Client Hints on Image Requests: What Chrome Sends
Chrome 155 sent DPR, width and network hints with image requests only after Accept-CH, and to another origin only with Permissions-Policy delegation. Width was in device pixels.
Client hints are request headers in which the browser tells the server about the device: its pixel density, the width an image will be displayed at, the network quality. An image server can use them to pick the right file without srcset. Chrome only sends most of them when the site asks for them with an Accept-CH response header. Which hints does Chrome 155 actually attach to image requests, with and without that header, and what about images from another domain? We logged the headers of every image request on a test page.
The test
A small local test server delivered a page with three images:
- a same-origin image with
width="400"and nosizes; - a same-origin image with
sizes="300px"; - the same
sizes="300px"image served from a second origin.
The page came in three versions: without Accept-CH; with Accept-CH listing the device, width, viewport and network hints; and with Accept-CH plus a Permissions-Policy header delegating the DPR, width, viewport-width and ECT hints to the second origin. We loaded each version twice in Chrome 155.0.8059.82 on screens of 1×, 2× and 3× density, and logged the request headers the image server received. See our methodology.
Results

| Server response | Screen | Image | Sec-CH-DPR | Sec-CH-Width | Sec-CH-Viewport-Width | ECT |
|---|---|---|---|---|---|---|
| no Accept-CH | 1× | same origin, width=400 | – | – | – | – |
| no Accept-CH | 1× | same origin, sizes=300px | – | – | – | – |
| no Accept-CH | 1× | other origin, sizes=300px | – | – | – | – |
| Accept-CH | 1× | same origin, width=400 | 1 | 400 | 412 | 4g |
| Accept-CH | 1× | same origin, sizes=300px | 1 | 300 | 412 | 4g |
| Accept-CH | 1× | other origin, sizes=300px | – | – | – | – |
| Accept-CH + Permissions-Policy delegation | 1× | same origin, width=400 | 1 | 400 | 412 | 4g |
| Accept-CH + Permissions-Policy delegation | 1× | same origin, sizes=300px | 1 | 300 | 412 | 4g |
| Accept-CH + Permissions-Policy delegation | 1× | other origin, sizes=300px | 1 | 300 | 412 | 4g |
| no Accept-CH | 2× | same origin, width=400 | – | – | – | – |
| no Accept-CH | 2× | same origin, sizes=300px | – | – | – | – |
| no Accept-CH | 2× | other origin, sizes=300px | – | – | – | – |
| Accept-CH | 2× | same origin, width=400 | 2 | 800 | 980 | 4g |
| Accept-CH | 2× | same origin, sizes=300px | 2 | 600 | 980 | 4g |
| Accept-CH | 2× | other origin, sizes=300px | – | – | – | – |
| Accept-CH + Permissions-Policy delegation | 2× | same origin, width=400 | 2 | 800 | 980 | 4g |
| Accept-CH + Permissions-Policy delegation | 2× | same origin, sizes=300px | 2 | 600 | 980 | 4g |
| Accept-CH + Permissions-Policy delegation | 2× | other origin, sizes=300px | 2 | 600 | 980 | 4g |
| no Accept-CH | 3× | same origin, width=400 | – | – | – | – |
| no Accept-CH | 3× | same origin, sizes=300px | – | – | – | – |
| no Accept-CH | 3× | other origin, sizes=300px | – | – | – | – |
| Accept-CH | 3× | same origin, width=400 | 3 | 1200 | 980 | 4g |
| Accept-CH | 3× | same origin, sizes=300px | 3 | 900 | 980 | 4g |
| Accept-CH | 3× | other origin, sizes=300px | – | – | – | – |
| Accept-CH + Permissions-Policy delegation | 3× | same origin, width=400 | 3 | 1200 | 980 | 4g |
| Accept-CH + Permissions-Policy delegation | 3× | same origin, sizes=300px | 3 | 900 | 980 | 4g |
| Accept-CH + Permissions-Policy delegation | 3× | other origin, sizes=300px | 3 | 900 | 980 | 4g |
Without Accept-CH, Chrome sent no device hints at all, only the low-detail browser hints it sends everywhere (Sec-CH-UA, Sec-CH-UA-Mobile and Sec-CH-UA-Platform).
With Accept-CH, the hints arrived on the very first visit. Because the header came with the page itself, Chrome attached the hints to that page’s own image requests immediately: Sec-CH-DPR matched the screen (1, 2 or 3), and ECT, RTT and Downlink described the connection.
Sec-CH-Width was in device pixels. For the image with sizes="300px", Chrome sent 300, 600 and 900 on 1×, 2× and 3× screens. For the image without sizes, it sent its width attribute times the density: 400, 800 and 1,200. A server can serve exactly that width without any srcset markup.
The image from another origin got nothing until delegated. With Accept-CH alone, the second origin received no device hints. With the Permissions-Policy delegation, it received exactly the delegated hints, and not the others.
Sec-CH-Viewport-Width needs care. On the 1× screen it reported 412, the real width. In Chrome’s mobile emulation at 2× and 3×, it reported 980, the default layout width that applies before a page’s viewport meta tag takes effect, even though our page had one. We would not rely on it for choosing image sizes.
What this means
- Client hints are opt-in. If your image service resizes by client hints, check that your pages send
Accept-CH; otherwise the service only sees the default browser hints. - Images on a CDN domain need delegation. Add a
Permissions-Policyheader such asch-dpr=(self "https://img.example.com")on your pages, or the CDN will not receive the hints. - Cache correctly. A server that changes the image according to a hint must send
Varyfor that hint, or caches may serve a 3× file to a 1× phone. We did not test caching here. - Keep
srcsetas the baseline. We tested Chrome only, and not every browser sends these hints, so markup-based responsive images, as in our srcset and sizes guide, remain necessary. - Width hints follow your
sizes. A wrongsizesgives a wrongSec-CH-Width, just as it gives a wrongsrcsetchoice in our grid layout test.
Example headers
Accept-CH: Sec-CH-DPR, Sec-CH-Width, ECT
Permissions-Policy: ch-dpr=(self "https://img.example.com"), ch-width=(self "https://img.example.com")
Vary: Sec-CH-DPR, Sec-CH-Width
The first two headers go on your HTML pages; Vary goes on the image responses that change with the hints.
Practical conclusion
Chrome 155 sent density, width and network hints with image requests only when the page asked for them with Accept-CH, and to another origin only when a Permissions-Policy header delegated them. Sec-CH-Width reported the display width in device pixels, from sizes or from the width attribute. Use hints to help an image service, but keep srcset for browsers that do not send them.
Limitations
Chrome only, with densities emulated through Playwright; the device memory and viewport values reflect the test machine and emulation. Browser support for client hints changes over time. We did not test the Critical-CH header, Save-Data with data saver enabled, or caching.
Data and files
Download client-hints-images.csv (54 rows, 12.7 KB) · Method: testing methodology. Photo: image credits.


