AmIUnique
Academic research tool that shows your fingerprint components. amiunique.org
Look, here’s the deal. You’ve built a perfectly good web scraper. It works flawlessly in development. Then you deploy it, and within 24 hours — blocked. Captchas everywhere. Access denied.
What happened? Browser fingerprinting happened.
Let me break this down in a way that actually makes sense, because most explanations out there are either too vague or buried in academic papers nobody reads.
Here’s something that’ll blow your mind: your browser is as unique as your actual fingerprint. Not kinda-sorta unique. We’re talking 99.1% unique according to the EFF’s Panopticlick research, which analyzed millions of browsers.
Think about that for a second. Out of every 286,777 browsers tested, only one had the same fingerprint as another. That’s insane.
And here’s the kicker — you don’t need cookies to be tracked. Fingerprinting works even in incognito mode, even with a VPN, even if you clear everything.
Your browser leaks information through dozens of channels. Here are the big ones:
| Fingerprint Vector | What It Reveals | Uniqueness Contribution |
|---|---|---|
| User Agent | Browser, OS, version | ~10% |
| Screen Resolution | Display size, pixel ratio | ~15% |
| Canvas Fingerprint | GPU rendering patterns | ~25% |
| WebGL Fingerprint | Graphics hardware details | ~20% |
| Audio Fingerprint | Audio processing signature | ~15% |
| Installed Fonts | System font list | ~10% |
| Timezone + Language | Geographic location hints | ~5% |
Combined, these create a hash that’s practically unique to your machine.
Canvas fingerprinting is the big one. It’s elegant, invisible, and devastatingly effective.
Here’s how it works:
// What detection scripts do (simplified)const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');
// Draw some text with specific fonts and stylesctx.textBaseline = 'top';ctx.font = '14px Arial';ctx.fillStyle = '#f60';ctx.fillRect(125, 1, 62, 20);ctx.fillStyle = '#069';ctx.fillText('Browser fingerprint', 2, 15);
// Add some curves and gradientsctx.arc(50, 50, 50, 0, Math.PI * 2, true);ctx.fill();
// Extract the pixel dataconst dataURL = canvas.toDataURL();const hash = murmurhash3(dataURL);
console.log(hash); // Unique per device!The magic? Different GPUs, different drivers, different anti-aliasing algorithms all produce subtly different pixel values when rendering the same content. We’re talking differences at the subpixel level — invisible to the human eye but perfectly detectable by code.
While canvas looks at 2D rendering, WebGL goes deeper — into your actual graphics hardware.
const canvas = document.createElement('canvas');const gl = canvas.getContext('webgl');
// Get the debug info extensionconst debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
// These reveal your exact GPUconst vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
console.log(vendor); // "Google Inc. (NVIDIA)"console.log(renderer); // "ANGLE (NVIDIA, NVIDIA GeForce RTX 3080 Direct3D11...)"That renderer string? It contains:
It’s like a serial number for your graphics card, broadcast to every website you visit.
Beyond the obvious vendor/renderer info, WebGL exposes dozens of parameters:
// Just a sample of what's exposedconst params = { MAX_TEXTURE_SIZE: gl.getParameter(gl.MAX_TEXTURE_SIZE), MAX_VERTEX_ATTRIBS: gl.getParameter(gl.MAX_VERTEX_ATTRIBS), MAX_VARYING_VECTORS: gl.getParameter(gl.MAX_VARYING_VECTORS), MAX_VERTEX_TEXTURE_IMAGE_UNITS: gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS), MAX_TEXTURE_IMAGE_UNITS: gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), SHADING_LANGUAGE_VERSION: gl.getParameter(gl.SHADING_LANGUAGE_VERSION), // ... 40+ more parameters};Each GPU has different capabilities, different limits. Combined, they create another unique signature.
This is my favorite because it’s so unexpected. Your browser’s audio processing creates a unique fingerprint.
const audioContext = new (window.AudioContext || window.webkitAudioContext)();const oscillator = audioContext.createOscillator();const analyser = audioContext.createAnalyser();const gain = audioContext.createGain();const processor = audioContext.createScriptProcessor(4096, 1, 1);
// Create a signal pathoscillator.type = 'triangle';oscillator.frequency.value = 10000;oscillator.connect(gain);gain.connect(processor);processor.connect(audioContext.destination);
// Process the audio and create a hashprocessor.onaudioprocess = function(event) { const samples = event.inputBuffer.getChannelData(0); const hash = computeHash(samples); // This hash is unique per device!};
oscillator.start(0);Why does this work? Different audio hardware, different drivers, different audio pipelines all process signals slightly differently. These floating-point differences create a unique signature.
Your navigator object is basically an open book:
const fingerprint = { // Browser identification userAgent: navigator.userAgent, platform: navigator.platform, vendor: navigator.vendor,
// Language preferences language: navigator.language, languages: navigator.languages,
// Hardware hints hardwareConcurrency: navigator.hardwareConcurrency, // CPU cores deviceMemory: navigator.deviceMemory, // RAM in GB maxTouchPoints: navigator.maxTouchPoints, // Touch capability
// Connection info connection: navigator.connection?.effectiveType,
// Plugins (still tracked, even though mostly empty now) plugins: Array.from(navigator.plugins).map(p => p.name),
// Do Not Track (ironically, enabling this makes you MORE unique) doNotTrack: navigator.doNotTrack,};Each of these individually isn’t very unique. But combined? They narrow down possibilities fast.
Here’s where it gets interesting. Fingerprints aren’t just used for tracking — they’re used for bot detection.
Modern anti-bot systems like Cloudflare, PerimeterX, and DataDome use a scoring model:
Trust Score = Σ(weight_i × factor_i)
Factors include:- Fingerprint consistency (all parts match?)- Fingerprint plausibility (does this make sense?)- Fingerprint uniqueness (is this a known "bot" print?)- Behavioral signals (mouse movements, typing patterns)- Network signals (IP reputation, ASN, etc.)Your fingerprint feeds directly into this score. Inconsistencies tank it.
Here’s an example of an inconsistent fingerprint that screams “bot”:
// Red flags everywhere{ navigator: { platform: "MacIntel", // Claiming to be Mac userAgent: "...(Windows NT 10.0)..." // But user agent says Windows! }, webgl: { renderer: "ANGLE (Intel...)" // Intel integrated graphics }, screen: { width: 800, height: 600, // Suspiciously small devicePixelRatio: 1 // No retina on "Mac"? }}A real Mac user wouldn’t have these contradictions. Detection systems flag this immediately.
Raw Puppeteer and Playwright have telltale signs:
// Detection scripts check for thesenavigator.webdriver; // true in automationnavigator.plugins.length; // 0 in headlesswindow.chrome; // undefined in some headless modesError().stack; // Contains "puppeteer" stringsIt’s a cat-and-mouse game. Detection systems add new checks; automation tools add patches. The cycle continues.
Let me share some data that’ll blow your mind. The fingerprinting landscape in 2026 is more sophisticated than ever:
| Metric | Value | Source |
|---|---|---|
| Top websites using fingerprinting | 10% of top 100k sites | Academic Research 2026 |
| Detected fingerprinting scripts | 0.78% of 988,220 websites | Computers & Security Study |
| Third-party fingerprinting | 50% prevalence on tracked domains | FP-tracer 2024 |
| First-party fingerprinting | 34% prevalence | FP-tracer 2024 |
| Metric | Value | Source |
|---|---|---|
| Unique browser fingerprints | 83.6% | EFF Panopticlick |
| Unique with Flash/Java enabled | 94.2% | EFF Research |
| Unique browser + device fingerprints | 99.24% | Combined Fingerprinting Study |
| Canvas fingerprint entropy | ~17 bits | Mozilla Research |
| WebGL fingerprint entropy | ~12 bits | Academic studies |
| Combined entropy | 30+ bits | Sufficient for unique ID |
Think about that 99.24% number for a second. Out of every 132 internet users, only one shares your exact fingerprint. You’re practically unique.
The anti-bot industry is booming. Here’s why fingerprinting matters more than ever:
| Metric | Value | Source |
|---|---|---|
| Bot detection market size (2026) | $1.04 billion | Mordor Intelligence |
| Projected market size (2030) | $4.52 billion | Mordor Intelligence |
| Growth rate (CAGR) | 26.18% | Industry reports |
| Cloudflare market share | 82.16% | Statista 2026 |
Here’s the kicker: DataDome’s 2025 Global Bot Security Report found that only 2.8% of websites are fully protected against bots (down from 8.4% in 2026), and over 61% failed every test.
This means two things:
For context: 33 bits of entropy can uniquely identify every human on Earth. Your browser typically leaks 30+ bits. You’re not anonymous. Never were.
Okay, enough doom and gloom. Here’s how you actually beat fingerprinting:
Instead of randomizing everything (which is suspicious), GoLogin generates internally consistent fingerprints:
// GoLogin ensures consistencyconst fingerprint = { navigator: { platform: "Win32", userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)..." }, webgl: { renderer: "ANGLE (NVIDIA, GeForce GTX 1080...)" // Windows + NVIDIA = ✓ }, screen: { width: 1920, height: 1080, // Common Windows resolution = ✓ devicePixelRatio: 1 }};Everything matches. Everything makes sense. No red flags.
GoLogin doesn’t block canvas — that’s detectable. Instead, it adds controlled noise:
// Subtle pixel-level modificationsconst originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
HTMLCanvasElement.prototype.toDataURL = function() { const ctx = this.getContext('2d'); const imageData = ctx.getImageData(0, 0, this.width, this.height);
// Add imperceptible noise for (let i = 0; i < imageData.data.length; i += 4) { imageData.data[i] += Math.floor(Math.random() * 2) - 1; // R imageData.data[i+1] += Math.floor(Math.random() * 2) - 1; // G imageData.data[i+2] += Math.floor(Math.random() * 2) - 1; // B }
ctx.putImageData(imageData, 0, 0); return originalToDataURL.apply(this, arguments);};The noise is tiny — ±1 on color values. Invisible to humans, but creates a different hash each time.
Replace those revealing hardware strings:
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
Object.defineProperty(gl, 'getParameter', { value: function(param) { if (param === debugInfo.UNMASKED_VENDOR_WEBGL) { return "Google Inc. (NVIDIA)"; } if (param === debugInfo.UNMASKED_RENDERER_WEBGL) { return "ANGLE (NVIDIA, NVIDIA GeForce GTX 1080 Direct3D11...)"; } return originalGetParameter.call(this, param); }});The key insight: real users have persistent fingerprints. They don’t change every session.
GoLogin maintains profiles across sessions. Same fingerprint. Same cookies. Same browsing history. To the website, you’re a returning user, not a new bot every time.
Want to see how unique you are? Here are some tools:
AmIUnique
Academic research tool that shows your fingerprint components. amiunique.org
BrowserLeaks
Comprehensive fingerprint analysis with technical details. browserleaks.com
CreepJS
Advanced fingerprinting detection, including lie detection. abrahamjuliot.github.io/creepjs
Bot Sannysoft
Quick check for common bot detection vectors. bot.sannysoft.com
After analyzing thousands of failed bot attempts, here are the mistakes I see over and over:
The Mistake: Using random values for every fingerprint component thinking it makes you “untraceable.”
Why It Fails: Real browsers don’t have random fingerprints. A Mac with an NVIDIA GPU? Impossible. Screen resolution of 723x891? Nobody has that. Detection systems flag these inconsistencies instantly.
The Fix: Use realistic, internally consistent fingerprints. If you’re spoofing Windows, use a Windows-appropriate GPU, screen resolution, and fonts.
The Mistake: Running puppeteer.launch({ headless: true }) and expecting it to work.
Why It Fails: navigator.webdriver returns true. navigator.plugins.length is 0. Window dimensions are suspicious. Detection scripts check for these.
The Fix: Use stealth plugins like puppeteer-extra-plugin-stealth or GoLogin which handles all patches automatically.
The Mistake: Rotating fingerprints thinking it provides “better coverage.”
Why It Fails: Real users don’t get new GPUs between page loads. A fingerprint that changes mid-session screams “bot.”
The Fix: Maintain profile persistence. Same fingerprint, same cookies, same browsing history across the entire session.
The Mistake: Disabling canvas or WebGL entirely to “prevent fingerprinting.”
Why It Fails: Blocking APIs is more suspicious than having a fingerprint. Sites detect when canvas returns null or errors.
The Fix: Return realistic values with subtle noise. Make the fingerprint plausible but not identical to your real hardware.
The Mistake: Using a US proxy with a Chinese timezone, or mismatched browser language.
Why It Fails: Real US users don’t have UTC+8 timezones. Detection systems correlate IP geolocation with timezone/language.
The Fix: Match timezone, language, and locale to your proxy’s geographic location.
The Mistake: Focusing only on JavaScript fingerprints while sending suspicious HTTP headers.
Why It Fails: Headers like Accept-Language, Accept-Encoding, and header order also fingerprint you.
The Fix: Use header profiles that match real browsers. Chrome, Firefox, and Safari all send different header combinations.
The Mistake: Deploying your scraper without checking if the fingerprint actually passes detection.
Why It Fails: You won’t know you’re caught until you’ve burned your IP addresses and profiles.
The Fix: Test against fingerprint checkers like CreepJS, Bot Sannysoft, and actual target sites before scaling.
Q: Can websites detect GoLogin or other antidetect browsers?
A: Not if configured correctly. The key is maintaining consistency and realism. GoLogin generates fingerprints based on real device data, making them indistinguishable from legitimate browsers. However, sloppy configuration (wrong timezone, suspicious behavior patterns) can still get you caught.
Q: How often should I change my browser fingerprint?
A: Think like a real user. Real people don’t buy new computers every day. Maintain the same fingerprint for weeks or months. Only rotate when you need to create a new “identity” or if a profile gets burned.
Q: Does using Incognito mode or a VPN protect against fingerprinting?
A: No. Fingerprinting works independently of cookies, IP addresses, or browsing mode. Your hardware and browser configuration create a unique signature regardless. VPNs change your IP but not your fingerprint.
Q: What’s the difference between canvas and WebGL fingerprinting?
A: Canvas fingerprinting analyzes 2D rendering patterns (how your GPU draws shapes and text). WebGL fingerprinting goes deeper, revealing your exact GPU model, drivers, and 3D rendering capabilities. WebGL is more invasive and harder to spoof convincingly.
Q: Can I use multiple profiles simultaneously on the same machine?
A: Yes, with tools like GoLogin. Each profile runs in isolation with its own fingerprint, cookies, and session data. To websites, they appear as completely different users on different devices.
Q: How do I know if my fingerprint is working?
A: Test it. Use AmIUnique to check uniqueness, BrowserLeaks for technical analysis, and Bot Sannysoft to verify you’re not flagged as a bot. If you pass all three, you’re in good shape.
Q: What about mobile fingerprints?
A: Mobile fingerprinting works similarly but focuses on touch events, device orientation, screen size, and mobile-specific APIs. Simulating mobile is harder because the fingerprint space is smaller (fewer device combinations), making anomalies more obvious.
Your browser is unique — Canvas, WebGL, audio, and dozens of other vectors create a fingerprint that’s practically impossible to share with anyone else.
Fingerprinting beats traditional privacy measures — Incognito mode, clearing cookies, using a VPN — none of these stop fingerprinting.
Bot detection relies on fingerprint consistency — Randomizing everything is actually MORE suspicious than having a consistent, realistic fingerprint.
The solution is simulation, not evasion — Instead of trying to hide your fingerprint, simulate a real one. That’s what GoLogin does.
Persistence matters — Real users don’t get new fingerprints every session. Neither should your bots.
Test before you deploy — Always verify your fingerprint passes detection before running at scale.
Ready to make your automation undetectable?