| Component name | hardware_concurrency |
|---|---|
| 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 | Brave (brave_farbling); Firefox resistFingerprinting and Tor Browser (firefox_rfp) |
| Inner timeout | 1000 ms |
| Added in | signalsVersion 1 |
Browsers tell pages how many tasks the processor can run at once, so that sites can split heavy work. A typical laptop says 8 or 12, a big desktop more, a phone usually 6 or 8. WhiskerJS reads this number as it is. Privacy browsers that fake it are skipped instead of read.
What it reads
navigator.hardwareConcurrency, reported as a plain number when it is a finite number.
How the technique works
The browser reports the number of logical processors available to it. WhiskerJS reads the property through the page’s navigator. If the property is missing or not a finite number the component is unavailable / no_api; if the getter throws (for example because a script replaced it with one that throws) the runner reports blocked / threw or security_error.
Why it helps
CPU thread counts differ across device classes and models, and they combine well with memory, architecture and screen values in the device group of the structuredId.
Stability
It is fixed for a given machine and browser, but it can change when a browser starts capping or rounding the value in an update, when a virtual machine is given a different number of processors, or on a different device.
Browser support and what blocks it
okin all current browsers (Chrome, Edge, Safari, Firefox, mobile browsers). Some browsers cap or round it; WhiskerJS reports what they give.- Brave:
excluded/brave_farbling. - Firefox resistFingerprinting and Tor Browser:
excluded/firefox_rfp.
Related integrity checks look at the same property: impossible_hardware (not a whole number from 1 to 256), navigator_own_property (defined on the navigator object itself), native_tampering (the getter does not look native) and iframe_mismatch (a clean frame reports a different number).
Privacy
A single number about the processor, 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 |
missing or not a finite number |
blocked |
security_error, threw |
the getter threw |
excluded |
brave_farbling, firefox_rfp, caller_excluded |
exclusion table or your list |
timed_out |
timeout, aborted |
1000 ms inner timeout, budget, abort |
Example value
"hardware_concurrency": { "status": "ok", "value": "8", "hashed": false }
The container test runs used for these pages reported 14 (headless Chromium and Firefox) and 8 (headless WebKit) on the same host, which shows that browsers do not all report the same number for one machine.
Questions and answers
Is hardware_concurrency the number of CPU cores?
It is the number of logical processors the browser exposes, which usually counts threads, not physical cores. Some browsers cap or round it.
Why is it excluded in Brave and Firefox resistFingerprinting?
Brave randomises it per site and session, and Firefox resistFingerprinting reports a fixed number. Neither describes the device, so the exclusion table skips it.
What does impossible_hardware mean?
The integrity check of that name fires when hardwareConcurrency is a number but not a whole number from 1 to 256, which points to a value set by hand.