TL;DR, Quick Answer
9 min readUser-Agent Client Hints are Chromium's replacement for the full User-Agent string. Every request carries three low-entropy headers, Sec-CH-UA, Sec-CH-UA-Mobile and Sec-CH-UA-Platform, with the browser brand, major version, a mobile flag and the OS name. A server asks for more, such as the OS version or device model, with an Accept-CH response header, or a script calls navigator.userAgentData.getHighEntropyValues(). Since Chrome 110 the UA string itself is frozen to fixed platform values. Firefox and Safari do not support client hints.
What are user agent client hints?
Chromium browsers send user agent client hints as a set of Sec-CH-UA request headers that carry browser and platform details in separate fields, and they send the detailed fields only when a server asks. Chrome's developer documentation says the model is one "where the server must ask the browser for a set of data about the client (the hints) and the browser applies its own policies or user configuration to determine what data is returned." The hints have been on by default since Chrome 89.
The old User-Agent header packed everything into one string on every request: browser, full version, operating system and version, and on Android the device model. Google's article on the change says that combination "could contain enough information to allow individual users to be uniquely identified." Client hints split it up so the default request carries less, and anything extra has to be requested in a way the browser can see.
If you run website analytics, this matters for two reports: browser and OS breakdowns, and device type. Both still work in Chrome, but some details that used to arrive for free now sit behind an opt-in.
- Browser and full version
- Operating system and version
- Device model on Android
- All of it on every request
- Browser brand and major version
- Mobile flag
- OS name
- Anything more waits until the server asks
Which Sec-CH-UA headers does Chrome send?
Chrome sends three Sec-CH-UA headers on every HTTPS request and holds back the rest until the server requests them. The WICG specification defines eleven headers. The ones that matter for analytics:
| Header | Example value | Entropy | Sent by default? |
|---|---|---|---|
Sec-CH-UA | "Chromium";v="93", "Google Chrome";v="93" | Low | Yes |
Sec-CH-UA-Mobile | ?0 for desktop, ?1 for mobile | Low | Yes |
Sec-CH-UA-Platform | "macOS" | Low | Yes |
Sec-CH-UA-Platform-Version | "10.0.0" | High | No, needs Accept-CH |
Sec-CH-UA-Full-Version-List | "Google Chrome";v="98.0.4738.0" | High | No, needs Accept-CH |
Sec-CH-UA-Model | "Pixel 3" | High | No, needs Accept-CH |
Sec-CH-UA-Arch | "arm" | High | No, needs Accept-CH |
Sec-CH-UA-Bitness | "64" | High | No, needs Accept-CH |
The spec also defines Sec-CH-UA-WoW64, Sec-CH-UA-Form-Factors and the deprecated Sec-CH-UA-Full-Version. Client hints only travel over secure connections, so a page served over plain HTTP gets none of them.
The brand list carries a deliberate oddity. It includes a fake brand such as " Not;A Brand";v="99", which Chrome's documentation calls GREASE and which can appear in any position with any name. MDN explains that it exists to prevent servers from "rejecting unknown user agents outright." Any parser you write has to ignore brands it does not recognize instead of matching on position.
What is the difference between low and high entropy hints?
Low-entropy hints are the fields a browser sends to every site because they reveal little beyond what other headers already show, and high-entropy hints are the fields that narrow a browser down far enough to help identify it. The WICG spec says the default hints expose "only the user agent's branding information, and the significant version number," both of which are "fairly clearly sniffable" from other headers and from which features the browser supports.
"High entropy" comes from information theory. Chrome's documentation describes the term as a reference to "the amount of information that these values reveal about the user's browser." A model name like Pixel 3 or an exact build like 98.0.4738.0 splits the population of Chrome users into far smaller groups than "Chrome 98 on Android" does. The browser fingerprinting guide explains how such fields add up when combined.

How does a site request high-entropy hints with Accept-CH?
A site requests high-entropy hints by returning an Accept-CH response header that names the hints it wants, after which the browser decides whether to send them on later requests to that origin. The exchange runs in four steps:
- The browser requests a page and sends only
Sec-CH-UA,Sec-CH-UA-MobileandSec-CH-UA-Platform. - The server responds with a header such as
Accept-CH: Sec-CH-UA-Full-Version-List, Sec-CH-UA-Model, or the page includes the same list in a<meta http-equiv="Accept-CH">tag. - Later requests to that origin carry the requested hints, if the browser's policy allows them.
- A new
Accept-CHheader replaces the previous set entirely, and an empty one clears it.
Three rules from Chrome's documentation trip people up. Hints requested through Accept-CH last "for the duration of the browser session or until a different set of hints are specified." They are sent on same-origin requests only, so a request to cdn.example.net gets nothing unless the page delegates each hint with a Permissions-Policy header. And a first visit carries only the default hints, because the server has not asked yet. Chromium documents a separate mechanism for hints a site needs on the first request.
Scripts have a second route. navigator.userAgentData exposes the low-entropy values as brands, mobile and platform, and navigator.userAgentData.getHighEntropyValues() returns a promise with fields such as model, platformVersion and fullVersionList. As with the headers, Chrome says "it's down to the browser what values, if any, are returned."
What did User-Agent reduction change in Chrome?
User-Agent reduction froze most of Chrome's User-Agent string to fixed values, so the old header now carries only the browser's major version, a fixed platform string and a mobile marker. The Chromium project rolled it out in phases:
| Chrome version | Release | Change to the UA string |
|---|---|---|
| Chrome 101 | April 26, 2022 | Minor, build and patch numbers frozen to 0.0.0 |
| Chrome 107 | October 25, 2022 | Desktop platform and OS version replaced with fixed values |
| Chrome 110 | February 7, 2023 | Android version fixed to 10 and device model replaced with K |
| Chrome 113 | 2023 | Reverse origin trial ended, so all page loads get the reduced string |
The fixed desktop platform values are literal strings. Chromium lists them as Windows NT 10.0; Win64; x64, Macintosh; Intel Mac OS X 10_15_7, X11; Linux x86_64 and X11; CrOS x86_64 14541.0.0, and every Android phone reports Linux; Android 10; K. Chromium notes that these "will not update even if a user is on an updated operating system or device." The reduction applies to Windows, macOS, Linux, ChromeOS and Chrome on Android. Chromium has no current plans for iOS or Android WebView.
The Chromium page is explicit about where the old detail went: "All of the information that was contained in the User-Agent string prior to reduction is available through the high entropy client hints."
Flowsery
Start Your 14-Day Free Trial
Real-time dashboard
Goal tracking
Cookie-free tracking
Which browsers support user agent client hints?
Chromium browsers support user agent client hints, and Firefox and Safari do not. MDN's browser compatibility data lists Sec-CH-UA as supported in Chrome and Edge from version 89 and Opera from version 75, and lists both Sec-CH-UA and Accept-CH as unsupported in Firefox and Safari. navigator.userAgentData follows the same split.
That leaves analytics with two parsing paths. In Chrome and Edge, the reduced UA string plus the low-entropy hints give browser, major version, OS name and a mobile flag. In Firefox and Safari, the User-Agent header is still the only source, and WebKit has frozen its own string too. Its tracking prevention page lists, among its anti-fingerprinting changes, that WebKit "altered the user agent string to not change with minor software updates."

What can an analytics tool still read for browser, OS and device reports?
An analytics tool still reads browser name, major version, OS family and mobile versus desktop from every Chrome visit without asking for anything, but the OS version and device model need high-entropy hints. The practical breakdown for a Chrome visitor:
| Report field | From the reduced UA string | From default low-entropy hints | Needs high-entropy hint |
|---|---|---|---|
| Browser name | Yes | Yes, Sec-CH-UA | No |
| Browser major version | Yes | Yes, Sec-CH-UA | No |
| Full browser version | No, shows .0.0.0 | No | Sec-CH-UA-Full-Version-List |
| OS name | Yes | Yes, Sec-CH-UA-Platform | No |
| OS version | No, fixed value | No | Sec-CH-UA-Platform-Version |
| Mobile or desktop | Yes, Mobile token | Yes, Sec-CH-UA-Mobile | No |
| Phone model | No, shows K | No | Sec-CH-UA-Model |
Every Windows 11 visitor in Chrome reports Windows NT 10.0 in the UA string, so a Windows 10 versus 11 split built on the UA string is wrong. Chrome on Android visits all claim version 10. If an OS-version chart in your analytics shows a single version taking over between late 2022 and mid-2023, that is the reduction, not your audience. Bot detection gets harder too, since an automated client copies a current Chrome string in one line of code; the guide to bot traffic filtering covers checks that do not rely on the UA alone.
Do user agent client hints reduce fingerprinting?
User agent client hints reduce passive fingerprinting, because a site no longer gets the full version, OS version and device model on every request, but they do not stop a script that asks for high-entropy values on purpose. The WICG spec states both halves: the goal is to "reduce the amount of default entropy exposed to the web at large," yet "it will still be possible for some, or all, hints to be requested and used for active fingerprinting purposes."
The difference is visibility. A request for Sec-CH-UA-Model shows up in the site's Accept-CH header or in a getHighEntropyValues() call, which privacy tools and auditors can detect. The old string handed out the same data silently. For a site owner, the rule is simple: request a high-entropy hint only when a feature needs it, such as picking the right download for a CPU architecture, and not to enrich analytics profiles.
What does Flowsery report about browsers and devices?
Flowsery reports device, browser and OS data in its analytics and does so without browser fingerprinting, without cookies in its cookieless mode and without storing personal data. Flowsery's API returns browser breakdowns with visitor counts and revenue per browser, filters by browser name such as Chrome, Safari, Firefox and Edge, with "Safari includes Mobile Safari automatically," and groups visitors by dimensions that include browser_version and os_version. The visitor endpoint returns device type, browser, OS and viewport dimensions from the most recent pageview. In cookieless mode Flowsery uses a daily-rotating visitor hash, so these fields describe sessions on your site without building a cross-day profile of a device, one reason unique visitors mean different things in different tools. The privacy-first analytics feature page lists what the tracker collects.
Frequently asked questions
Are user agent client hints replacing the User-Agent header?
No, Chrome still sends the User-Agent header, but in a reduced form with a frozen minor version and fixed platform values. The detail removed from it is available through high-entropy client hints, which a site has to request.
Does Firefox send Sec-CH-UA headers?
No. MDN's compatibility data lists Sec-CH-UA and Accept-CH as unsupported in Firefox and Safari. Those browsers still describe themselves through the User-Agent header only.
Why does my analytics show every Android user on Android 10?
Chrome 110 fixed the Android version in the UA string to 10 and replaced the device model with K. Any tool that parses only the UA string reports Android 10 for every Chrome on Android visit. The real version needs the Sec-CH-UA-Platform-Version hint.
Can analytics tell Windows 11 from Windows 10 in Chrome?
Not from the UA string, which reports Windows NT 10.0 for both. A site that requests Sec-CH-UA-Platform-Version through Accept-CH, or calls getHighEntropyValues(), receives the platform version Chrome chooses to share.
Do I need HTTPS for client hints?
Yes. Chrome sends client hints only over secure connections, so a site on plain HTTP receives no Sec-CH-UA headers at all.
Are high-entropy client hints personal data?
On their own, a device model or OS build number does not name a person. Combined with other signals into a stable identifier, they become part of a fingerprint, and a fingerprint that singles out a device counts as personal data under GDPR, which is why privacy-first analytics avoids building one.
What is the fake brand in the Sec-CH-UA header?
It is a GREASE entry such as " Not;A Brand";v="99", and it can appear in any position with any name. It exists to prevent servers from rejecting unknown user agents outright. A parser should ignore brands it does not recognize instead of matching on position.
Flowsery
Start Your 14-Day Free Trial
Real-time dashboard
Goal tracking
Cookie-free tracking
How do I get the full Chrome version or device model in analytics?
Return an Accept-CH header that names the hints you want, such as Sec-CH-UA-Full-Version-List and Sec-CH-UA-Model. A script can also call navigator.userAgentData.getHighEntropyValues(). In both cases the browser decides what, if anything, it returns.
Do client hints reach requests to other domains?
Hints requested through Accept-CH are sent on same-origin requests only. A request to cdn.example.net gets nothing unless the page delegates each hint with a Permissions-Policy header.
Does Chrome send high-entropy hints on the first visit?
A first visit carries only the three default hints, because the server has not asked for more yet. Once the server sends Accept-CH, later requests include the requested hints for the browser session or until a different set is specified. Chromium documents a separate mechanism for hints a site needs on the first request.
Was This Article Helpful?
Let us know what you think!
See us more often in Google
One click marks Flowsery as a preferred source, so our articles sit higher in your Top Stories, AI Mode, and AI Overviews.
Before you go...
Flowsery
Revenue-first analytics for your website
Track every visitor, source, and conversion in real time. Simple, powerful, and cookie-free.
Real-time dashboard
Goal tracking
Cookie-free tracking
Related Glossary Terms


Why CNAME Cloaking No Longer Hides Trackers From Safari or Brave
Trackers used CNAME cloaking to pose as your subdomain. See how the DNS trick works, why Safari caps its cookies at 7 days and how Brave and uBlock uncloak it.


How Cookie Syncing Matches Ad IDs Across Websites
Ad-tech firms use cookie syncing to swap user IDs through redirects and pixels. See what Safari, Firefox and Chrome do about it and why analytics skips it.


How to Build GA4 Calculated Metrics Inside a Five-Slot Quota
Google caps GA4 calculated metrics at 5 per standard property. Learn the formula syntax, the units, where they appear and what a formula can't use.


Setting Up GA4 Content Grouping With One Parameter
Set up GA4 content grouping with the content_group parameter in gtag or Tag Manager, read the Content group dimension and keep (not set) rows out.


Why Unique Visitors Meaning Changes From Tool to Tool
The unique visitors meaning depends on the tool: GA4 estimates it, Matomo refuses to compute it on long ranges, Adobe dedupes it across the whole report.


Google Lists Seven Separate Causes of not set in GA4
Google's docs give not set in GA4 a different cause per dimension, from a missing session_start to an empty content_group. Here is each cause and its fix.
Related Articles


How CHIPS Partitioned Cookies Give Each Site Its Own Jar
Setting CHIPS partitioned cookies takes Secure, SameSite=None and one more attribute, and the browser keeps a separate copy per top-level site.


Reversibility decides pseudonymisation vs anonymisation under the GDPR
Reversibility decides pseudonymisation vs anonymisation. Article 4(5) data stays personal data. Recital 26 anonymous data leaves the GDPR for good.
What Server Side Tracking Fixes, and What It Leaves Untouched
Learn what server side tracking moves to your own server, which Safari cookie caps it escapes, how to deduplicate events, and why consent obligations stay.

