What a fingerprint actually is
A browser fingerprint is not one number. It's a vector of dozens of independently-readable properties that, combined, are stable and often unique to a device — without any cookie. Because so many properties are read together, changing one rarely breaks the match, and changing one incoherently creates a new signal. For the short version, see what is browser fingerprinting?
It helps to group the signals by where they originate. Signals within a family tend to be correlated; the interesting failures happen between families.
1. Rendering signals
These come from asking the machine to draw something and reading back the result: Canvas 2D (draw text/shapes, hash the pixels), WebGL (geometry, shaders, readPixels, plus the UNMASKED_VENDOR/UNMASKED_RENDERER strings), WebGPU adapter info, and AudioContext output. Sub-pixel differences from the GPU, driver and font rasterizer make them distinctive.
The trap here is that the strings and the output must agree. Claiming a particular GPU in the WebGL vendor string while the actual pixels were rendered by a different one is a classic incoherence. This is why deep coherence sometimes means rendering on the GPU class you claim, rather than just rewriting the label — the idea behind Clearcote's canvas bridge. See also canvas fingerprinting
2. Hardware signals
navigator.hardwareConcurrency (CPU cores), deviceMemory, screen geometry and pixel ratio, maxTouchPoints, and pointer/hover media capabilities. Individually mundane; collectively they sketch a device class.
Coherence rules bite hard here. A "phone" persona with a desktop screen ratio, a mouse pointer, zero touch points and 32 CPU cores is not a phone. These values have to be chosen together from a plausible device, which is why persona selection — not per-field randomization — is the right unit of control.
3. Locale & environment signals
Timezone, navigator.language(s), the Accept-Language header, installed fonts, and geolocation. These describe where and who, and they're the signals most likely to contradict a proxy.
The common failure: routing through an egress in one country while the browser still reports the home timezone, language and locale. Each value is fine alone; together with the IP they're incoherent. A coherent setup moves timezone, locale and language to match the egress — ideally automatically from the proxy's geolocation.
4. Network signals
Below the page entirely: the TLS ClientHello (summarized as a JA3/JA4 hash), the HTTP-2 settings and frame ordering, and the request headers. A server reads these before a byte of JavaScript runs.
Because JavaScript can't touch this layer, it's the ultimate coherence check: a browser that claims Chrome in its UA but presents a non-Chrome (or wrong-version) handshake has an unbridgeable gap. Keeping the wire coherent with the claimed version — only the version-variant fields changing, the rest staying real-Chrome — is a network-layer job, not a script one.
The through-line
Read this way, the whole fingerprint surface is one consistency problem. Uniqueness is what lets a site recognize you again; incoherence between the four families is what marks you as automation. Any control that fixes one family while ignoring the others just moves the tell.
That's the case for deriving everything from a single persona and enforcing it in the engine — so the rendering, hardware, locale and network stories are the same story. If you want to go deeper on the detection side, read coherence over camouflage or the detection breakdown in the docs.