navigator.hardwareConcurrency is a read-only JavaScript property defined in the WHATWG HTML Living Standard that returns the number of logical processor cores available to a web page or Web Worker. It works in Chrome 37+, Edge 15+, Firefox 48+, Safari 10.1+ on macOS, Safari 10.3+ on iOS, Opera 24+, and Samsung Internet 4+, while Internet Explorer never added support.
This guide covers what navigator.hardwareConcurrency is, which browsers support it, how to use it, its use cases, and its known limitations.
What is navigator.hardwareConcurrency?
navigator.hardwareConcurrency is a read-only property on the Navigator object and on a Web Worker's WorkerNavigator. It returns an integer between 1 and the number of logical processor cores the browser exposes. The WHATWG HTML Living Standard defines it under the NavigatorConcurrentHardware mixin in section 10.2.7.
Which browsers does navigator.hardwareConcurrency support?
Every modern desktop and mobile browser supports navigator.hardwareConcurrency. Internet Explorer never added support, and Safari clamps the value on macOS and iOS to limit hardware fingerprinting.
Loading browser compatibility data...
navigator.hardwareConcurrency compatibility in Chrome
Chrome supports navigator.hardwareConcurrency from Chrome 37 on Windows, macOS, Linux, ChromeOS, and Android. Chrome 4 to 36 did not support it. Chrome on Android shares the same Blink build as desktop, so the Android version reports the same logical-core integer as the desktop builds on the same machine class.
navigator.hardwareConcurrency compatibility in Edge
Microsoft Edge supports navigator.hardwareConcurrency from Edge 15 on Windows. The legacy EdgeHTML versions (Edge 12 to 14) did not support it. The Chromium-based Edge from Edge 79 on inherits the property on Windows, macOS, Linux, Android, and iOS through the same Blink pipeline as Chrome.
navigator.hardwareConcurrency compatibility in Firefox
Firefox supports navigator.hardwareConcurrency from Firefox 48 on desktop and on Firefox for Android. Firefox 2 to 47 did not support it. When the privacy.resistFingerprinting preference is on in about:config, Firefox returns a fixed value of 2 instead of the real core count to reduce fingerprint entropy.
navigator.hardwareConcurrency compatibility in Safari
Safari supports navigator.hardwareConcurrency from Safari 10.1 on macOS and Safari 10.3 on iOS and iPadOS. Safari 8 to 10 had it disabled by default behind a flag, and Safari 3.1 to 7.1 did not support it. WebKit caps the returned value at 8 on macOS and at 2 on iOS to limit hardware fingerprinting on Apple devices.
navigator.hardwareConcurrency compatibility in Opera
Opera supports navigator.hardwareConcurrency from Opera 24 on Windows, macOS, and Linux through the Chromium 37 base. Opera 9 to 23 did not support it. Opera Mobile added support from Opera Mobile 80 on Android. Opera Mini still does not expose the property, since the proxy-rendered pages skip Web Worker code.
navigator.hardwareConcurrency compatibility in Samsung Internet
Samsung Internet has supported navigator.hardwareConcurrency since Samsung Internet 4 on Galaxy phones and tablets. The browser reads the value through the same Blink pipeline as Chrome on Android, so a recent Samsung flagship returns the same integer as Chrome on the same device.
navigator.hardwareConcurrency compatibility in Android Browser
The legacy stock Android Browser, frozen at version 4.4 before Chrome for Android took over, does not support navigator.hardwareConcurrency on Android 4.4 and earlier. On modern Android phones, use Chrome for Android, Samsung Internet, or any other Chromium-based browser to read the property.
navigator.hardwareConcurrency compatibility in Internet Explorer
Internet Explorer never added navigator.hardwareConcurrency support. IE 5.5 through IE 11 cannot read the property, and any access returns undefined. Microsoft has retired Internet Explorer, so use Edge, Chrome, or Firefox to read the value on Windows.
Note: navigator.hardwareConcurrency reports different values on Safari macOS, Safari iOS, and Firefox in privacy mode. Test it on real browsers and OS with TestMu AI. Try TestMu AI free!
How do you use navigator.hardwareConcurrency?
Read navigator.hardwareConcurrency in any modern browser to get the number of logical cores the browser exposes, then size your Web Worker pool, thread budget, or parallel queue against that integer.
- Open the DevTools console: Press F12 or right-click and choose Inspect, then switch to the Console tab in any supported browser.
- Read the property: Type navigator.hardwareConcurrency and press Enter. The returned integer is the number of logical cores the browser is willing to expose.
- Add a fallback for older browsers: Use navigator.hardwareConcurrency || 2 so single-threaded pages still get a sensible default if the property is undefined.
- Size your Web Worker pool: Spawn one Worker for each logical core, up to a project-specific cap, and reuse the pool across tasks instead of creating new Workers per request.
- Verify on real devices: Run the snippet on a Mac, an iPhone, and a low-end Android to see the WebKit cap in action and confirm your fallback path triggers when expected.
const cores = navigator.hardwareConcurrency || 2;
console.log(`This browser reports ${cores} logical cores.`);
const workerPool = [];
for (let i = 0; i < cores; i++) {
workerPool.push(new Worker("task-runner.js"));
}
console.log(`Spawned ${workerPool.length} workers for parallel work.`);
If the snippet logs 1 in a browser you expect to support the API, the page is likely running with privacy.resistFingerprinting on, in a private window with extra hardening, or inside a clamped WebKit build on iOS.
What are the use cases of navigator.hardwareConcurrency?
Anything that scales with parallelism uses navigator.hardwareConcurrency to decide how much work to fan out, from Web Worker pools and WebAssembly threads to adaptive UI on low-end devices.
- Web Worker pools: Spawn one Worker per logical core to run image filters, codecs, or heavy parsers without blocking the main thread.
- WebAssembly threading: Multi-threaded WebAssembly modules read the property at startup to set their thread budget, matching the browser's exposed core count.
- Adaptive performance tiers: A device reporting 2 cores can drop heavy effects, lower video resolution, or skip animations to keep the page responsive.
- Render scheduling: Game engines and 3D apps split the render loop, physics worker, and asset decoder across the reported core budget for smoother frame pacing.
- Heuristic device classification: Combined with navigator.deviceMemory, the core count helps split traffic into low, mid, and high tiers without server-side detection.
- Background work throttling: A page can pause analytics, prefetching, or service-worker tasks on a 2-core report and let them catch up on a 16-core machine.

What are the limitations of navigator.hardwareConcurrency?
navigator.hardwareConcurrency is a useful hint, but the value is shaped by browser caps, privacy spoofing, and hyperthreading rather than the raw silicon underneath.
- Capped on Safari: WebKit returns at most 8 on macOS and at most 2 on iOS, so a 24-core Mac Pro and a 4-core M-series iPad both report the cap rather than the real count.
- Privacy spoofing in Firefox and Brave: Firefox returns 2 when privacy.resistFingerprinting is on. Brave randomizes the value between 2 and the true count or 8, depending on the shield mode.
- Logical, not physical: The number includes hyperthreaded virtual cores, so an 8-physical-core CPU may report 16. The browser cannot distinguish physical from logical cores.
- No CPU detail: The property does not expose architecture, clock speed, big.LITTLE topology, or current load. Two devices with the same core count can have very different real performance.
- Static read: It returns a single integer, with no event for thermal throttling, power-state changes, or VM resizing. Reading it once at startup is the standard pattern.
In my experience, the bigger trap is treating the value as a hard hardware count: a 16-core MacBook reports 8 in Safari and a 4-core M-series iPad reports 2, so any worker pool sized strictly to navigator.hardwareConcurrency runs well below the real ceiling on Apple devices. Always feature-detect, cap your pool against your own constants, and verify the live value on a real device.

Citations
All navigator.hardwareConcurrency version numbers and platform notes in this guide come from these primary sources: