Skip to main content
A persona presents a GPU from a GPU family. A GPU family is a set of WebGL and WebGPU values measured on real hardware. The family gives the WebGL limits, extensions and shader precision and the WebGPU adapter. The model within the family gives the renderer string. How it works explains how the families were measured.

The families

GPU models lists every model with its renderer string.

How a persona picks one

The seed picks a family of the persona’s platform, whatever GPU the host has:
  • A Windows persona on an x86 host picks the NVIDIA or the Intel Direct3D 11 family, with equal odds.
  • A Windows persona on an ARM host gets the Qualcomm family. The persona reports the host’s CPU family, and a Windows machine with an ARM CPU has a Qualcomm GPU.
  • A macOS persona gets the Metal family.
  • A Linux persona gets the Vulkan family.
The seed then picks a model from the family, with the weights in the catalogue. The model decides the machine class, core count and memory, and the machine class decides the screen. A persona never picks SwiftShader. Only --fingerprint-anchor selects it. --fingerprint-explain shows the family and model a launch picked:

What WebGL and WebGPU report

That output is from a Mac. A page reads the same values on any host, with one exception. On Linux, requestAdapter() returns null in headless launches and in headed launches as root, so the script above fails at adapter.info there. Known gaps tracks it. Within a family, every model has the same WebGL limits, extensions and shader precision and the same WebGPU features and limits. The WebGPU architecture follows the model’s chip generation, and so does the smallest subgroup size on Intel’s 12th-generation models. navigator.gpu exists only on secure pages, such as https:// and http://localhost.

Name a model

--fingerprint-gpu-renderer sets the model. The value is the whole WebGL renderer string, exactly as GPU models lists it, and it must be a model of the family the launch uses. Seed 42 as a Windows persona uses the Intel family, so an NVIDIA string is refused:
The browser exits with status 1. Through the packages, the same refusal raises LaunchError in Python and BrowserLaunchError in Node, with this text in the message. --fingerprint-anchor selects the family. With the NVIDIA family, the same renderer is accepted:
Naming a model can change more than the renderer, because the machine class, core count and memory follow the model. For seed 42, the RTX 4070 turns a small-form-factor desktop with 8 GiB into a tower with 16 GiB:
--fingerprint-gpu-vendor sets the WebGL unmasked vendor string, such as Google Inc. (NVIDIA), and the seed picks a model with that vendor from the family. A vendor the family does not have is refused the same way.

Choosing a family

Use --fingerprint-anchor with a family of the persona’s own platform. The browser accepts a family of another platform, such as a Direct3D 11 family under a Linux persona, and such a machine does not exist.
An id that is not in the table above is not refused. The browser logs --fingerprint-anchor named '...', which is not in the compiled catalogue to stderr and presents the host’s own values for every surface. Copy the id exactly.

Rendering stays on the host

The browser reports the persona’s GPU, but the host draws. Canvas, WebGL and WebGPU pixels, and the time they take, come from the host’s GPU, or from SwiftShader when the host has none. On a host without a GPU, the claimed WebGPU adapter runs on SwiftShader, and features the software device cannot back fail when a page calls requestDevice(). Known gaps lists what a page can measure, and Hosts which hosts suit which persona. Personas of one platform on one host draw the same canvas image unless their fonts differ.

Readback noise

--fingerprint-noise changes canvas and WebGL pixel readback by at most one step per colour channel, on pixels at colour edges. Solid areas and alpha stay as rendered. The change depends only on the seed and the pixels, so the same seed reads back the same bytes every time, and getImageData(), toDataURL(), toBlob() and WebGL readPixels() agree with each other. The first 8 bytes of the SHA-256 of one canvas’s toDataURL(), for seeds 1 and 2 as Windows personas on one host: Noise is off by default and does nothing in host mode. A page can detect it, for example by drawing one image at two scales and comparing them. Turn it on only when canvas hashes must differ between personas on one host. The switch takes no value. --fingerprint-noise=false turns noise on, so the packages refuse it and any other value that reads as off.