Open the developer tools on any website you've ever visited and look at the request headers. Buried in the list is a line that looks something like this:

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36

That's the User-Agent string, and your browser sends it with every single request — every image, script, font, API call, the lot. It's the browser's self-introduction: this is who I am, this is the OS I'm running on, this is roughly what I can render.

The string is also one of the strangest artefacts on the modern web. It's a tangle of historical compatibility quirks layered on top of historical compatibility quirks, where Chrome claims to be Safari, Safari claims to be a Mozilla browser, and somewhere in there is an honest answer about which one is actually loading the page. This post pulls the string apart and explains what each piece means, why it's there, and what's replacing it.

What a User-Agent string is for

The header was originally introduced so servers could do content negotiation — return different content depending on which client was asking. A text-only browser couldn't render images, so the server might skip the <img> tags. A mobile browser in 2007 couldn't run complex JavaScript, so the server might send a stripped-down version of the page. A search engine crawler doesn't need the full UI, so the server might send a faster path optimised for indexing.

That principle still exists today. A site might serve different CSS to mobile vs desktop based on the UA. Bot detection systems use it as one of many signals. Analytics tools use it to chart browser market share. Feature detection sometimes falls back to UA sniffing when there's no cleaner alternative.

What was supposed to be a small piece of metadata grew into a kitchen-sink of information that sites quietly use for everything from layout decisions to advertising targeting. Every request from your browser hands all of it over before you've clicked a thing.

Anatomy of a real UA string

Let's break apart that Chrome example token by token:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36

Mozilla/5.0 — This is the part that confuses everyone. Chrome isn't Mozilla. Neither is Safari, or Edge, or Opera. But all of them start their UA strings with Mozilla/5.0 anyway. The reason is purely historical: in the 1990s, Netscape Navigator was dominant, and sites began checking for Mozilla (Netscape's project codename) to decide which features to serve. When Internet Explorer wanted to receive the same "modern" content, it started identifying itself as Mozilla too. Then Firefox did. Then Safari. Then Chrome. Nobody can stop because every site is still checking. This is sometimes called the User-Agent train wreck.

(Macintosh; Intel Mac OS X 10_15_7) — The platform parenthetical. The OS family (Macintosh / Windows NT / X11; Linux / Android / iPhone), processor architecture if relevant (Intel Mac, ARM Mac), and the OS version. This is the only part of the string that comes close to telling the honest truth.

AppleWebKit/537.36 — The rendering engine. WebKit is the engine Safari uses; Chrome's engine (Blink) forked from WebKit in 2013, but it kept the WebKit token in the UA because, again, sites were sniffing for it. The version number 537.36 has been frozen for years even as both engines have evolved hugely.

(KHTML, like Gecko) — KHTML is the rendering engine WebKit forked from in 2001. Gecko is Firefox's engine. This phrase exists because in the early days, sites that wanted to gate on "modern engine" would check for either KHTML or Gecko. Including both tokens covers more bases. None of this is true any more — Chrome doesn't use KHTML or Gecko in any meaningful sense — but the words remain.

Chrome/126.0.0.0 — This is finally the honest part. The actual browser, with a version. (As of 2026 the minor version digits are intentionally zeroed out in Chrome's default UA — see the next section.)

Safari/537.36 — A compatibility token. Chrome appends Safari/ at the end because Apple-only sites used to check for "Safari" in the UA before serving Safari-specific content. Sound familiar?

The result of all this layering: a string where every browser pretends to be every other browser, and the only piece of information you can really trust is the version number of whichever browser actually wrote the string.

The User-Agent reduction and Client Hints

The UA string is a privacy problem and an engineering eyesore at the same time. The version-number drift it captures (Chrome's exact build, the OS's exact build, the CPU architecture) leaks dozens of bits of entropy — enough to contribute meaningfully to browser fingerprinting. And the spec has been frozen by convention for so long that adding new information is impossible: the format is part of the contract.

Google's answer is the User-Agent reduction, rolled out across Chrome from 2022 onward. Modern Chrome's default UA carries only the major version, only a generic "macOS 10.15.7" (regardless of actual macOS version), and no detailed CPU model. The full information is still available — but only on request, via a separate mechanism.

That mechanism is User-Agent Client Hints. Instead of dumping everything into one header that every site receives unconditionally, the browser advertises which fields it can provide, and the server explicitly opts in to receiving them. The new headers look like this:

Sec-CH-UA: "Not_A Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"
Sec-CH-UA-Platform: "macOS"
Sec-CH-UA-Mobile: ?0

A site can also request Sec-CH-UA-Platform-Version, Sec-CH-UA-Arch, Sec-CH-UA-Model, and Sec-CH-UA-Bitness by sending an Accept-CH response header listing the fields it wants. The browser then sends those headers on subsequent requests. Detailed information is no longer free.

For developers this is a meaningful shift. Sites that genuinely need browser version information must opt in explicitly and (in principle) declare why. Sites that just want to know "mobile or desktop?" can use a single boolean field instead of regex-ing a 200-character string. Firefox and Safari haven't fully adopted Client Hints — both still rely on the classic UA string, with their own privacy-focused reductions on top — but the direction is clear.

What websites actually do with this

The honest answer: it depends on the site. The common uses fall into a handful of categories.

  • Content negotiation. Server-side rendering of a different layout for mobile vs desktop. Largely supplanted by responsive CSS, but still used by sites with completely separate mobile codebases.
  • Bot and crawler handling. Search engines, archivers, and AI training crawlers identify themselves so sites can decide whether to allow, throttle, or block them.
  • Analytics. Charting which browsers and OS versions your users have, so you know what to test against.
  • Compatibility shims. Buggy old browser? Insert a polyfill. Less common now that the long tail of IE has died.
  • Feature detection. Sometimes there's no JavaScript API to ask "do you support X?" and the answer has to be inferred from the UA. This is fragile and discouraged, but it happens.
  • Fingerprinting. Combined with screen size, timezone, fonts, and a dozen other signals, the UA contributes to a fingerprint that can re-identify a visitor across sessions — even without cookies. See our browser fingerprint tool for what your own setup looks like.

The trouble with all of these is that the UA can be spoofed trivially. A two-line browser extension can change the string to anything. curl --user-agent sets whatever you want. Bots routinely impersonate Chrome on Windows to evade simple "block crawlers" rules. Anything downstream of the UA needs to be treated as a hint, not a fact.

Bot detection via User-Agent

Honest crawlers identify themselves. Googlebot's UA looks like this:

Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/W.X.Y.Z Safari/537.36

Bingbot, GPTBot (OpenAI's crawler), ClaudeBot (Anthropic's), PerplexityBot — they all follow the same pattern: a recognisable token in the UA plus a URL where you can read about what they do and how to opt out. If you operate a site, your robots.txt rules and any per-bot exclusions key off these tokens.

The problem is that scrapers, scraping-as-a-service vendors, and the more aggressive AI crawlers often don't identify themselves. They send a UA that looks like Chrome on Windows and proceed to fetch 50,000 pages an hour. The UA alone is no defence.

The trick the major search engines all support is reverse-DNS verification: take the bot's IP, do a PTR lookup, check that the result is in the expected domain (googlebot.com, search.msn.com, etc.), then forward-resolve the hostname and confirm it points back to the same IP. If the round-trip lines up, the bot is who it says it is. If not, the UA is lying. Our WHOIS & reverse DNS tool covers the manual version of this check.

Privacy and fingerprinting

Every bit of unique information your browser leaks contributes to a fingerprint. The classic UA string is a generous contributor: the combination of browser, browser version, OS, OS version, and (until recently) CPU architecture and exact build numbers is enough to put most users in groups of a few thousand. Combine that with screen resolution, installed fonts, timezone, and graphics card, and the group shrinks to one.

The User-Agent reduction is a meaningful privacy improvement, because it removes the unique-version-number signal from the default UA and forces sites to opt in to the detailed data. But it doesn't end fingerprinting. The information that's still in the reduced UA — major Chrome version, OS family — combined with the dozens of other signals available via the JavaScript API is still enough to distinguish users reliably. Killing the UA entirely is not on the table; too much of the web depends on it.

If you care about minimising what you leak, the things that move the needle are: keep your browser updated (so you're in the largest possible "current version" cohort), use a browser with built-in anti-fingerprinting (Firefox and Brave both have meaningful protections), and don't use random plugins that change your UA — they make you more unique, not less. The fingerprinting deep-dive covers the full picture.

The User-Agent string is one of the oldest pieces of the web that's still actively in use. It's been broken for most of that time, in the sense that what it says and what it means are different things — and the modern web is finally inching toward replacing it with something more honest. Until that's done, every request you make still hands over a small declaration of who you are. It's worth knowing what's in it.

Try it

Check what your browser is sending right now

Parsing a UA string by eye gets tedious fast. Our tool breaks down your current browser's User-Agent into browser, OS, device, and engine — and shows you the Client Hints your browser advertises, if any.

See my User Agent →