Deterministic Browser Mode: Reproducible Fingerprints Across Sessions
How to produce identical browser fingerprints across sessions using noise seed control for consistent Canvas, WebGL, and Audio output.
Introduction
Browser fingerprinting relies on signals that are stable within a session but vary between devices. The flip side of this problem is reproducibility: when you need multiple browser sessions to present the same identity, or when you need to verify that your privacy protection is working correctly, you need deterministic behavior. A browser that produces slightly different canvas hashes, audio fingerprints, or WebGL output each time it launches makes it impossible to maintain a stable identity or to reliably test your configuration. BotBrowser's deterministic mode, enabled through the --bot-noise-seed flag, gives you complete control over all sources of fingerprint variation. The same profile and seed combination always produces the same fingerprint, across sessions, across machines, and across operating systems.
Privacy Impact
The need for deterministic browser behavior comes from a fundamental tension in fingerprint protection. Noise is important for privacy. Adding controlled variation to canvas output, audio processing, and WebGL rendering prevents fingerprints from being trivially linked to a single profile. But uncontrolled noise, where every session produces a different fingerprint, creates a different problem: each session appears as a unique user, which is the opposite of blending in.
Research from the INRIA privacy team has shown that fingerprint instability (changing fingerprints across sessions) is itself a tracking signal. If a fingerprint changes on every visit but other signals (IP, login state, behavioral patterns) remain stable, the changing fingerprint becomes a marker rather than a shield.
Deterministic mode solves this by giving you explicit control. You choose when fingerprints should stay the same (same seed) and when they should differ (different seed). This is particularly important for:
- Session continuity. Returning to a website across multiple sessions with the same fingerprint.
- Multi-instance coordination. Running multiple browser instances that need distinct but stable identities.
- Testing and verification. Confirming that your fingerprint protection produces expected results.
- Research reproducibility. Running controlled experiments where fingerprint variation must be eliminated as a variable.
Technical Background
Sources of Fingerprint Variation
Modern fingerprint protection involves adding controlled noise to several rendering and processing pipelines:
- Canvas 2D. Text rendering, shape drawing, and image manipulation produce device-specific pixel output. Noise adds sub-pixel variation to prevent exact matching.
- WebGL/WebGPU. Shader execution, texture sampling, and framebuffer readback produce GPU-specific output. Noise modifies pixel values in the rendered output.
- Audio. OfflineAudioContext rendering and AnalyserNode frequency data produce platform-specific float values. Noise varies the processing output.
- Text metrics.
measureText(),getBoundingClientRect(), andgetClientRects()return dimensions that depend on font rendering. Noise adds sub-pixel variation to measurements.
Without a seed, each of these noise sources generates fresh random variation on every browser launch. With a seed, the random number generator is initialized to a known state, producing identical variation patterns every time.
How Noise Seeds Work
A noise seed is a single integer that initializes a deterministic pseudo-random number generator (PRNG). The PRNG produces a sequence of values that appears random but is entirely determined by the seed. Two sessions with the same seed produce the same sequence, and therefore the same noise applied to every fingerprint surface.
BotBrowser's noise seed (set via --bot-noise-seed) controls:
- Canvas 2D image noise
- WebGL image noise
- WebGPU rendering noise
- Audio context processing variation
- Text metric variation (client rects, text rects)
- Text layout variation
The seed does not affect non-noise properties like navigator.hardwareConcurrency, screen.width, or user agent strings. These come directly from the profile and are always deterministic.
Timing Determinism
Beyond fingerprint noise, BotBrowser offers additional timing controls:
--bot-time-seed- Controls execution timing diversity across 27 browser operations. Each seed produces a unique, stable performance profile. This coversperformance.now()intervals,performance.getEntries(), navigation timing, and more.--bot-time-scale- Scales downperformance.now()intervals to normalize timing differences caused by varying server loads.
Together, noise seeds and timing seeds provide comprehensive deterministic control over all variable browser outputs.
Common Protection Approaches and Their Limitations
No noise at all means your fingerprint directly reflects the profile's base values. This is deterministic but removes the privacy benefit of variation. Multiple sessions with the same profile all have the exact same fingerprint, which means they are linkable by definition.
Random noise without a seed provides variation but at the cost of reproducibility. Every session has a unique fingerprint. You cannot maintain a stable identity, you cannot verify your configuration reliably, and you cannot coordinate multiple instances.
Session-based noise (generating a random seed per session and storing it) is a manual workaround that adds complexity. You need to manage seed values, associate them with sessions, and ensure they are applied consistently. BotBrowser eliminates this overhead by accepting the seed as a CLI flag.
Extension-based noise typically applies random noise at the JavaScript level without any seed mechanism. Each page load produces different results. The noise is not deterministic, not controllable, and not consistent across API surfaces.
BotBrowser's Engine-Level Approach
BotBrowser's deterministic mode operates at the rendering engine level, ensuring that noise is applied consistently across all API surfaces from a single seed value.
Single Seed, Complete Coverage
The --bot-noise-seed flag accepts an integer from 1 to 4294967295 (UINT32_MAX). This single value controls all noise sources simultaneously:
- Canvas 2D
toDataURL(),toBlob(), andgetImageData()produce identical output for the same seed. - WebGL
readPixels()returns the same framebuffer data for the same drawn scene and seed. - OfflineAudioContext renders the same buffer for the same audio graph and seed.
measureText()andgetClientRects()return the same measurements for the same content and seed.
Cross-Machine Reproducibility
Because the noise is derived from the seed and applied at the engine level, the same profile + seed combination produces the same fingerprint regardless of the underlying hardware, operating system, or GPU. A session on a Linux server with an NVIDIA GPU and a session on a Mac laptop with Apple Silicon produce identical fingerprints when using the same profile and seed.
Seed as Identity
In practice, you can think of each seed as defining a unique sub-identity within a profile. Profile A with seed 42 is a stable, reproducible identity. Profile A with seed 43 is a different stable, reproducible identity. The profile defines the device class (OS, browser, hardware), and the seed defines the individual within that class.
This model maps naturally to multi-account or multi-session workflows:
- Session 1: profile A, seed 100
- Session 2: profile A, seed 200
- Session 3: profile B, seed 100
Sessions 1 and 2 appear as different users with similar hardware. Session 3 appears as a different user on different hardware.
Timing Determinism
With --bot-time-seed, execution timing becomes reproducible too. Performance measurements, navigation timing, and resource timing all follow a deterministic pattern for a given seed. Combined with --bot-noise-seed, this provides complete control over all variable browser outputs.
Configuration and Usage
Basic Deterministic Mode
chrome --bot-profile="/path/to/profile.enc" \
--bot-noise-seed=42 \
--user-data-dir="$(mktemp -d)"
Full Deterministic Control
chrome --bot-profile="/path/to/profile.enc" \
--bot-noise-seed=42 \
--bot-time-seed=42 \
--bot-stack-seed=profile \
--user-data-dir="$(mktemp -d)"
Multi-Instance with Distinct Seeds
# Instance 1 - stable identity A
chrome --bot-profile="/path/to/profile.enc" \
--bot-noise-seed=1001 \
--user-data-dir="/tmp/session-a" &
# Instance 2 - stable identity B
chrome --bot-profile="/path/to/profile.enc" \
--bot-noise-seed=1002 \
--user-data-dir="/tmp/session-b" &
Playwright Integration
const { chromium } = require('playwright');
const browser = await chromium.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
'--bot-noise-seed=42',
'--bot-time-seed=42'
]
});
const page = await browser.newPage();
await page.goto('https://example.com');
// This canvas fingerprint will be identical on every run
const hash = await page.evaluate(() => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.fillText('deterministic test', 10, 10);
return canvas.toDataURL();
});
console.log(hash);
Puppeteer Integration
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({
executablePath: '/path/to/botbrowser/chrome',
defaultViewport: null,
args: [
'--bot-profile=/path/to/profile.enc',
'--bot-noise-seed=42',
'--bot-time-seed=42'
]
});
const page = await browser.newPage();
await page.goto('https://example.com');
Disabling Specific Noise Channels
If you need deterministic output for some signals but native output for others:
chrome --bot-profile="/path/to/profile.enc" \
--bot-noise-seed=42 \
--bot-config-noise-canvas=false \
--bot-config-noise-audio-context=false
Verification
Cross-session reproducibility. Run the same fingerprinting test in two separate sessions with the same profile and seed. Compare canvas hashes, audio fingerprints, WebGL output, and text metrics. All values should be identical.
Cross-machine reproducibility. Run the same test on a different machine with the same profile and seed. The fingerprint should match exactly.
Seed variation. Change the seed and run the test again. The fingerprint should be different, confirming that the seed is actually influencing the output.
Seed 0 behavior. Using --bot-noise-seed=0 keeps noise active with profile defaults but without deterministic seeding. Verify that this produces varying output across sessions.
Best Practices
- Use a unique seed per identity. Each seed defines a stable sub-identity. Do not reuse the same seed for sessions that should appear as different users.
- Store seed values. If you need to return to a session, you need the same profile and seed. Store the association between session identity and seed value.
- Combine
--bot-noise-seedwith--bot-time-seed. Noise seed controls rendering output. Time seed controls performance timing. Both contribute to a complete fingerprint. Use both for full determinism. - Avoid seed value 0. Zero keeps noise active with non-deterministic variation. Use any positive integer for deterministic behavior.
- Test your seed assignments. Before deploying, verify that different seeds produce different fingerprints and that the same seed produces identical fingerprints.
FAQ
Q: What is the valid range for --bot-noise-seed? A: Any integer from 1 to 4294967295 (UINT32_MAX). The value 0 keeps noise active but non-deterministic.
Q: Does the noise seed affect browser performance? A: No. The noise operations are extremely lightweight. The PRNG computation adds negligible overhead.
Q: Can two different profiles with the same seed produce the same fingerprint? A: No. The profile defines the base fingerprint (GPU, screen, navigator, etc.), and the seed defines the noise variation. Different profiles with the same seed produce different fingerprints because the base values differ.
Q: What happens if I do not set --bot-noise-seed? A: Noise is applied with a random seed on each launch. Each session has a different fingerprint. The profile's base properties (navigator, screen, etc.) remain the same.
Q: Does deterministic mode affect cookies or local storage?
A: No. Deterministic mode controls fingerprint-relevant rendering output. Storage, cookies, and session state are managed through --user-data-dir and --bot-cookies.
Q: Can I use the same seed with different BotBrowser versions? A: The noise algorithm may change between major versions. For exact reproducibility, use the same BotBrowser version. Within a version, seed behavior is guaranteed stable.
Q: How does --bot-time-seed differ from --bot-noise-seed?
A: --bot-noise-seed controls rendering noise (canvas, WebGL, audio, text metrics). --bot-time-seed controls execution timing diversity (performance.now() patterns, navigation timing). They are independent and can be set to different values.
Summary
Deterministic browser behavior is essential for maintaining stable fingerprint identities, coordinating multi-session workflows, and verifying privacy protection. BotBrowser's --bot-noise-seed flag provides complete control over all sources of fingerprint variation, producing identical output for the same profile and seed combination regardless of the underlying hardware. Combined with --bot-time-seed for timing determinism and --bot-stack-seed for stack depth control, BotBrowser offers a comprehensive deterministic mode that covers every variable browser output.
For related topics, see What is Browser Fingerprinting, Audio Fingerprint Protection, Canvas Fingerprinting, and Noise Seed Reproducibility.