Audio fingerprint
Your Audio Fingerprint
A stable hash derived from OfflineAudioContext + DynamicsCompressor, plus your device's sample rate, latency, and channel count.
Audio fingerprint
Rendering 44100 offline samples...
How the hash is computed
We create an OfflineAudioContext(1, 44100, 44100), generate a 10 kHz triangle wave, route it through a DynamicsCompressor with fixed parameters, and render 44,100 samples. We then sum the absolute values of a fixed slice (samples 4500 to 4999) and hash that sum with FNV-1a. Because the compressor is DSP-heavy and floating-point-sensitive, tiny differences in the underlying math library shift the sum, and the hash.
Why scrapers get flagged
The most common cloud CPUs (Graviton, generic KVM Skylake, GCP N2) each produce a small handful of distinct audio hashes. If your headless Chrome runs on any of them, your hash almost certainly matches a hash that's already been seen from other suspicious traffic.
Fixes
- Use a stealth plugin that injects fixed per-session noise into the compressor output.
- Run on the same CPU family as your target audience (Windows x86 laptops).
- Or delegate to a scraping API that handles audio + canvas + WebGL noise for you.
Frequently asked questions
→What is an audio fingerprint?
It's a hash derived from how your browser and hardware render a synthesized audio signal. The standard trick is to feed a triangle wave into a DynamicsCompressor node inside an OfflineAudioContext, then read a slice of the resulting waveform back and hash it. Different CPUs, ARM vs x86, browser versions, and DSP implementations produce different floating-point rounding, and therefore different hashes.
→Is the audio hash stable across sessions?
Yes, on the same device and browser build the hash is deterministic. That's exactly why it's used for tracking. It's also why anti-bot vendors can maintain lists of known-bad hashes from popular headless setups.
→Why does the audio API expose latency and sample rate?
The Web Audio API needs to tell developers how to schedule audio in real time, so it exposes AudioContext.baseLatency, outputLatency, sampleRate, and channel counts. Those values differ by device and OS and add extra entropy on top of the compressor hash.
→Can I block audio fingerprinting?
Firefox with resistFingerprinting enabled returns constant, spoofed values. Brave adds per-session noise. In Chrome you need an extension. For scrapers, patch OfflineAudioContext.startRendering() to inject tiny consistent noise per session, same strategy as canvas.
→Why don't all headless browsers fail the audio check?
Software audio works fine in headless mode; there's no equivalent of SwiftShader for audio. What gives them away is that a small set of cloud VM CPUs (AWS Graviton, GCP Cascade Lake, etc.) each produce a distinct, well-known hash. Anti-bot vendors have those hashes catalogued.