Pick a host for a persona
There is no build for Intel Macs or 32-bit Windows. Do not run the Linux x64 build under x86 emulation on an ARM machine. In a Docker container under Rosetta on an Apple silicon Mac, FingerprintJS Pro reported
developer_tools on every run, host mode included (measured 2026-09-23, development build before Apostate 0.4.0, Windows persona and host mode).
ARM hosts
A page can tell the CPU family from arithmetic, such as the sign bit of a computed NaN, and from Web Audio output, which the host CPU renders. When a Windows persona on an Apple silicon Mac claimed an x86 CPU, FingerprintJS Pro flagged the session asvirtual_machine, which reads as x86 Windows emulated on ARM. Claiming arm cleared the flag (measured 2026-09-23 on an Apple silicon Mac, development build before Apostate 0.4.0, Windows persona).
Windows and Linux personas therefore report the host’s CPU architecture in Sec-CH-UA-Arch and navigator.userAgentData. On an ARM host they report arm. The release has no Windows-on-ARM GPU family, so the GPU next to that arm is always a desktop Intel or NVIDIA part. A real Windows-on-ARM laptop pairs arm with a Qualcomm Adreno GPU, and an Adreno family is planned. iphey.com flags that pair as “inconsistent browser fingerprint (butterfly)”. macOS personas always report arm, which matches an ARM host and not an x86 one.
For Windows and Linux personas, use an x86 Linux server or a Windows machine. For a macOS persona, use a Mac. Known gaps has the measurements.
GPU-less servers
A Linux server with no GPU runs every persona. The persona still names its GPU family’s hardware, and WebGL reports the family’s limits and extensions. A software renderer, SwiftShader or Mesa’s llvmpipe, draws the pixels. In a headed launch as a regular user, WebGPU serves the persona’s adapter with SwiftShader underneath. In headless mode, and in headed mode as root,navigator.gpu.requestAdapter() returns null (Known gaps).
The browser treats a Linux host as GPU-less when it has no readable and writable DRM render node, or when you pass --disable-gpu. What changes:
- A page that times drawing sees software speed.
- A WebGPU feature or limit that SwiftShader cannot back fails when a page calls
requestDevice()with it. - WebGL extensions that add methods, such as
WEBGL_provoking_vertex, are missing when the software renderer lacks them. - A headed launch needs a display. The packages start Xvfb for you; install it with
sudo apt install xvfb.
Cores and memory
A persona never claims more cores or memory than the host has. The browser drops options above the host’s before the draw, and when no option fits, the page reads the host’s own value. On a small server, most Windows personas report the server’s own core count next to a desktop GPU. How often that happens, for 400 Windows seeds (0 to 399) composed with the 0.4.3 tables byscripts/profile_resolver.py, which matches the browser’s compositor:
A host with 16 logical cores and 32 GiB never shows its own counts under a Windows persona. A host with 64 cores and 128 GiB can serve every option in the tables. Memory is compared with what the host’s OS reports. Seeds and identity explains how the cap moves a seed’s machine between hosts.
What stays the host’s
These come from the host whatever the persona. Known gaps has each one with what you can do about it.- Canvas, WebGL and WebGPU pixels, and how fast they are drawn.
- Glyph shapes and metrics, drawn by FreeType on Linux, CoreText on macOS and DirectWrite on Windows.
- Which fonts exist. A persona hides fonts; it cannot add one the host lacks.
- CPU arithmetic and Web Audio output, which reveal the CPU family.
- The hardware video encoders WebRTC offers.
- Passkey capabilities from
PublicKeyCredential.getClientCapabilities(). - The Widevine module and the first message it sends.
- Cameras, microphones and speakers the host has.
- File path parsing on a Windows host.
- The height of the tab strip and toolbar,
outerHeight - innerHeight. A Windows persona reads 87 at 100% scaling (Known gaps).