| Component name | pixel_ratio |
|---|---|
| In the visitorId | no (reported, kept out of both ids) |
| structuredId group | none |
| 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 |
Sharp screens pack more physical pixels into each unit a web page uses for layout; the browser reports this as the pixel ratio (for example 2 on many phones and Retina laptops). The same number also changes when you zoom a page. So WhiskerJS reports it for your server to look at, but never lets it change the identifiers.
What it reads
window.devicePixelRatio.
How the technique works
The number is read once and rounded to three decimals with WhiskerJS’s own rounding (so 1.2500000001 becomes 1.25). A value that is not a finite positive number gives unavailable.
Why it helps
It reflects the screen density and the operating system’s display scaling (for example 1.25 or 1.5 on Windows laptops), which separates many devices. That is useful context for your server, for example to check that a phone user agent comes with a phone-like ratio. It is not used for matching because it is not stable.
Stability
Low on desktop: page zoom changes it, and so can moving the window to a monitor with different scaling. On phones it is usually fixed. This is exactly why it is kept out of both ids: neither the visitorId nor the structuredId moves when a user zooms.
On your server, if you compare two results from the same device and only pixel_ratio differs, the user most likely zoomed or moved the window. Nothing in the ids changes in that case, which is the intended behaviour.
Browser support and what blocks it
- Available everywhere: Chrome, Firefox, Safari, iOS browsers, Android browsers.
- Firefox resistFingerprinting and Tor Browser:
excludedwith ruleIdfirefox_rfp, because the value is normalised to 1 there. A pixel ratio of 1 is also one of the traits WhiskerJS needs before it classes a Firefox asfirefox_rfp.
Privacy
It describes screen density and the zoom level at that moment. It is not stored and does not join an id.
How WhiskerJS handles noise and failures
| Status | ruleId | When |
|---|---|---|
ok |
the ratio, up to three decimals | |
unavailable |
no_api |
not a finite positive number |
excluded |
firefox_rfp |
browser class firefox_rfp |
excluded |
caller_excluded |
you excluded it |
timed_out |
timeout, aborted |
budget or abort |
Example value
All three headless test browsers in the container reported 1. Typical values elsewhere: 2, 3, 1.25, 1.5.
Questions and answers
Why is pixel_ratio not in the visitorId?
In desktop browsers, zooming the page in or out changes devicePixelRatio. If it were in the id, a user pressing Ctrl and plus would get a new id.
Why is it excluded under Firefox resistFingerprinting?
resistFingerprinting reports a pixel ratio of 1 regardless of the screen, so reading it adds nothing. The exclusion table reports it as excluded with ruleId firefox_rfp.
What can my server use it for?
As a consistency hint: a phone user agent with a ratio of 1, or a value that does not fit the reported screen, is worth a look. Do not use it to match devices.