| Component name | device_memory |
|---|---|
| In the visitorId | yes |
| structuredId group | device (screen, memory, CPU) |
| Hashing | plain value; a digest only when longer than 128 characters or not printable ASCII |
| Excluded under | no browser class |
| Inner timeout | 1000 ms |
| Added in | signalsVersion 1 |
Chrome and other Chromium-based browsers tell pages roughly how much memory the device has, rounded to a few fixed steps such as 4 or 8 GB, so sites can serve lighter pages to small devices. Safari, every browser on iPhone and iPad, and Firefox do not offer this. WhiskerJS reads it where it exists and reports “unavailable” elsewhere, which is expected.
What it reads
navigator.deviceMemory, reported as a plain number when it is a finite number.
How the technique works
The browser rounds the real memory to a coarse value before exposing it, so pages only learn a bucket. WhiskerJS reads the property; a missing property gives unavailable / no_api, a throwing getter blocked.
Why it helps
The bucket separates device classes (small phones, mid-range laptops, large desktops) and combines with CPU threads, architecture and the heap limit in the device group. Its absence also carries information: an unavailable value next to a Chrome user agent is unusual and worth a look on your server.
Stability
Fixed for a given device and browser. It changes only on a different device, or when a browser changes its bucketing.
Browser support and what blocks it
okin Chromium-based browsers: Chrome desktop, Chrome on Android, Edge, Brave (not in Brave’s exclusion row), Samsung Internet.unavailable/no_apiby design in Safari on macOS, every iOS browser and Firefox.
The early lab sample, an early, small sample at signalsVersion 1, not a benchmark, matched this: device_memory was unavailable on Mac Safari, iPhone Safari and iPhone Chrome (which runs on WebKit), and each of the four device-browser pairs still kept one id across its runs.
Related checks: impossible_hardware fires when the value is a number but not a power of two from 0.25 to 64, navigator_own_property and iframe_mismatch look at the same property.
Privacy
A coarse bucket chosen by the browser to limit what pages learn. Read without permission or prompt, never sent by WhiskerJS.
How WhiskerJS handles noise and failures
| Status | ruleId | When |
|---|---|---|
ok |
none | for example 8 |
unavailable |
no_api |
not offered (Safari, iOS, Firefox) or not a number |
blocked |
security_error, threw |
the getter threw |
excluded |
caller_excluded |
your exclude list |
timed_out |
timeout, aborted |
1000 ms inner timeout, budget, abort |
Example value
"device_memory": { "status": "ok", "value": "8", "hashed": false }
In Safari and Firefox: { "status": "unavailable", "ruleId": "no_api" }.
Questions and answers
Why is device_memory unavailable on my iPhone or in Safari?
Only Chromium-based browsers offer navigator.deviceMemory. Safari, every iOS browser (they all run on WebKit) and Firefox do not, so the component is unavailable with ruleId no_api by design.
Does an unavailable device_memory change the visitorId?
Not from run to run. Every non-ok status adds the same placeholder line, so a browser that never offers the API gives a stable id.
Can device_memory report my exact RAM?
No. Browsers round it to a coarse bucket, such as 4 or 8, on purpose.