| Component name | webgl_renderer |
|---|---|
| In the visitorId | yes |
| structuredId group | gpu (graphics) |
| Hashing | plain value; a digest only when longer than 128 characters or not printable ASCII |
| Excluded under | Firefox resistFingerprinting and Tor Browser (firefox_rfp) |
| Inner timeout | 1000 ms |
| Added in | signalsVersion 1 |
Browsers can tell a page which graphics chip draws its 3D content, for example “Apple M2” or a model of Intel, AMD or NVIDIA GPU, often wrapped in the name of the browser’s graphics layer. WhiskerJS reads that name as text. It is one of the most readable device details there is, and it also shows when there is no GPU at all.
What it reads
From the shared WebGL 1 context:
- in browsers other than Firefox, WhiskerJS asks for the
WEBGL_debug_renderer_infoextension and, when it exists, readsUNMASKED_RENDERER_WEBGLwithgetParameter(); - if that gives nothing (no extension, or an empty answer), it reads the plain
gl.RENDERERvalue instead; - in Firefox (browser class
firefoxorfirefox_rfp) the extension is not requested at all: Firefox prints a deprecation warning in the console when it is, and its plainRENDERERalready carries the unmasked string. WhiskerJS writes nothing to the console, so it avoids that call.
An empty result is unavailable / no_value.
How the technique works
The browser’s “masked” renderer value is often a generic word such as “WebKit WebGL”. The debug extension exposes the underlying string the graphics driver reports. Chromium browsers usually wrap it in ANGLE, the translation layer they use, for example ANGLE (Apple, ANGLE Metal Renderer: Apple M2, Unspecified Version). The string is reported as is unless it is longer than 128 characters or not printable ASCII, in which case it is hashed like any other value.
The raw string is also kept, inside the library only, for the software_renderer check, which fires when it names SwiftShader, llvmpipe, softpipe, a “software rasterizer”, the “basic render driver” or Mesa offscreen.
Why it helps
It names the GPU family and often the model and graphics back end (Metal, Direct3D, OpenGL, Vulkan). That separates devices clearly and, read together with the platform and the user agent your server sees, can expose inconsistencies such as a desktop GPU on a phone user agent. It is in the gpu group.
Stability
Stable until the browser or driver changes how the GPU is described, or a different GPU is used (an external display on a laptop with two GPUs, or hardware acceleration switched off). Browser updates sometimes change the ANGLE wrapping text.
Browser support and what blocks it
okwherever WebGL 1 is available: Chrome, Edge, Brave, Safari, Firefox and mobile browsers. Some browsers report only a generic name (the headless WebKit test run in a container used for these pages reportedApple GPU).- Firefox resistFingerprinting and Tor Browser:
excluded/firefox_rfp. - No WebGL:
unavailable/no_context.
Privacy
It reveals the graphics hardware, which is device information and can be personal data together with the rest of the result. It is read without any permission or prompt and nothing is sent by WhiskerJS. Long or unusual strings leave only as a digest.
How WhiskerJS handles noise and failures
| Status | ruleId | When |
|---|---|---|
ok |
none | plain text, or a digest when long or not printable ASCII |
unavailable |
no_value |
both the unmasked and the plain value were empty |
unavailable |
no_document, no_api, no_context |
no document, no getContext, no WebGL |
unavailable |
no_digest |
the string needed hashing and Web Crypto is missing |
blocked |
security_error, threw |
getParameter threw |
excluded |
firefox_rfp, caller_excluded |
exclusion table or your exclude list |
timed_out |
timeout, aborted |
1000 ms inner timeout, overall budget, abort |
Example value
From a headless Chromium test browser in a container, drawing in software:
"webgl_renderer": {
"status": "ok",
"value": "ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (LLVM 10.0.0) (0x0000C0DE)), SwiftShader driver)",
"hashed": false
}
That run also had the software_renderer flag. On a typical Mac with Chrome the docs show ANGLE (Apple, ANGLE Metal Renderer: Apple M2, Unspecified Version).
Questions and answers
Why does my renderer say SwiftShader or llvmpipe?
The browser is drawing in software instead of on a GPU: hardware acceleration is off, the GPU is blocklisted, or the machine is a server, container or virtual machine. WhiskerJS then also sets the software_renderer integrity flag.
Is the renderer string ever hashed?
Only when it is longer than 128 characters or contains a character outside printable ASCII. Otherwise it is reported as plain text with hashed false.
Why is it excluded under Firefox resistFingerprinting?
That mode replaces the WebGL strings with placeholders, so the value would not describe the device. The exclusion table reports excluded with ruleId firefox_rfp.