Overview
When running multiple Chrome instances in parallel using multiprocessing or multithreading, you must follow a specific setup pattern to prevent binary conflicts. Multiple processes attempting to download and patch the same ChromeDriver binary simultaneously will cause failures.The Correct Pattern
The key is to callPatcher.patch() once before spawning multiple processes, then use user_multi_procs=True in each worker process.
Complete Example
Here’s the exact pattern from the source code:How It Works
Pre-patch the binary
Patcher.patch() downloads and patches a ChromeDriver binary before any processes are spawned.Why This is Required
Without user_multi_procs (Default Behavior)
By default, eachuc.Chrome() instance:
- Downloads a fresh ChromeDriver binary
- Patches it to remove detection signatures
- Uses it for the session
- Deletes it when
quit()is called
With user_multi_procs=True
When you setuser_multi_procs=True:
- The instance skips the automatic patching step (undetected/init.py:211-212)
- It uses the pre-patched binary created by
Patcher.patch() - The binary is shared across all processes
- No race conditions or file conflicts occur
Advanced Multiprocessing Example
Here’s a more complete example with error handling and result collection:Using the Spawn Context
Always use thespawn context for maximum compatibility:
Common Patterns
Pattern 1: Parallel Scraping
Pattern 2: Worker Pool
Troubleshooting
Binary not found error
Binary not found error
Error:
No undetected chromedriver binary were foundSolution: Make sure Patcher.patch() is called before spawning processes:Permission errors on binary
Permission errors on binary
Error:
PermissionError: [Errno 13] Permission deniedSolution: This happens when processes try to modify the same binary. Ensure user_multi_procs=True is set:Processes hang or timeout
Processes hang or timeout
Problem: Processes don’t completeSolutions:
- Use headless mode to reduce resource usage
- Limit the number of concurrent processes
- Add timeouts to
join()calls - Ensure
driver.quit()is always called (use try/finally)
Platform-Specific Notes
Windows
On Windows, thespawn context is the default. Always use if __name__ == "__main__": to prevent infinite process spawning.
Linux/macOS
Whilefork is the default on Unix systems, spawn is recommended for consistency:
Performance Considerations
- Each Chrome instance uses ~100-200MB of RAM
- Limit concurrent instances based on available system resources
- Use headless mode when visual rendering isn’t needed
- Consider using a process pool instead of spawning processes individually
What Not to Do
Next Steps
- Review Basic Usage for single-instance patterns
- Learn about Custom Options for worker configuration
- Check Troubleshooting for more common issues