1. Why Selenium Grids Get Blocked
A Selenium Grid's whole appeal is running many browser sessions in parallel — which is also exactly what gets it blocked fastest if every node shares the same outbound IP. From a target site's perspective, dozens of simultaneous sessions all originating from one address is about as clear a bot signal as exists. The fix isn't reducing parallelism; it's making sure each node, or even each session, routes through its own residential IP so the parallelism doesn't concentrate onto a single address the target can flag.
2. Where Proxy Config Fits in Grid Architecture
A standard Selenium Grid has a hub that receives test/scraping requests and distributes them to registered nodes, each of which runs its own browser instances. Proxy configuration can be applied at two different points in that chain, and picking the right one matters:
Routes sessions to nodes. Doesn't touch browser traffic directly — not the place to configure proxies.
Hosts browser instances. Can be configured with a fixed proxy, but that ties every session on that node to one IP.
Individual browser capability. The most flexible level — each session can request its own proxy via desired capabilities.
3. Prerequisites
A running Selenium Grid with hub and at least one node already registered and healthy.
SafestProxy gateway credentials, with rotating-session usernames prepared for each parallel worker.
A Selenium client library (Python, Java, or Node) that supports setting proxy in desired capabilities.
4. Setting Proxy via Browser Capabilities
Selenium's WebDriver protocol accepts a proxy object as part of the desired capabilities sent when a new session is requested — this is the session-level approach from the architecture table above, and the one that gives you the most control in a distributed grid.
// Python example: setting proxy via capabilities
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy, ProxyType
proxy = Proxy()
proxy.proxy_type = ProxyType.MANUAL
proxy.http_proxy = "user-rotate:YOUR_PASSWORD@gate.safestproxy.com:7000"
proxy.ssl_proxy = "user-rotate:YOUR_PASSWORD@gate.safestproxy.com:7000"
capabilities = webdriver.DesiredCapabilities.CHROME.copy()
proxy.add_to_capabilities(capabilities)
driver = webdriver.Remote(
command_executor='http://hub-address:4444/wd/hub',
desired_capabilities=capabilities
)5. Step-by-Step Setup
Generate a unique session username per worker
Before requesting a session, build a rotating or sticky username with a session ID unique to that worker or task.
Build the Proxy capability object
Set the HTTP and SSL proxy fields to your gateway address with the worker's credentials embedded.
Attach it to the desired capabilities
Merge the proxy object into your browser's capabilities before requesting a remote session from the hub.
Request the session from the hub
The hub assigns the session to an available node — the proxy travels with the session regardless of which node handles it.
Verify and run
Load an IP-check page as the session's first navigation, then proceed with your actual test or scraping logic.
6. Per-Node vs Per-Session Proxy Assignment
| Approach | How it works | Best for |
|---|---|---|
| Per-node | Node itself is launched with a fixed proxy config | Simple grids with few nodes and low session concurrency |
| Per-session | Each WebDriver session sets its own proxy via capabilities | Larger grids needing independent IPs per parallel session |
Per-session is the better default for most scraping or automation grids, since it decouples IP assignment from physical infrastructure — you can scale sessions up without needing a matching number of differently-configured nodes.
7. Scaling Nodes Without Colliding Sessions
When adding more nodes to handle higher concurrency, make sure your session-ID generation logic scales with it — a common mistake is reusing a small, fixed pool of session IDs across many more parallel sessions than the pool was designed for, which causes multiple unrelated sessions to collide onto the same sticky IP. Generate session IDs dynamically per task (a UUID or task ID works well) rather than from a short hardcoded list.
8. Common Pitfalls
01 Hardcoding proxy config at the node level
This ties every session on that node to one IP, undermining the entire point of a distributed grid for scraping.
02 Reusing session IDs across parallel workers
Colliding session IDs cause unrelated workers to share a sticky IP, creating unpredictable rate-limit behavior.
03 Not setting both http_proxy and ssl_proxy
Leaving ssl_proxy unset means HTTPS traffic can bypass the proxy entirely — set both fields explicitly.
04 Skipping health checks on nodes
A node with a broken proxy connection will silently fail every session routed to it — monitor node-level success rates, not just grid-level ones.
9. Troubleshooting
Capabilities malformed. Double-check the proxy object structure matches what your Selenium client version expects — this has changed across major versions.
Proxy unreachable from that node. Confirm the node's network allows outbound connections to the gateway host and port.
Proxy silently bypassed. Usually means ssl_proxy wasn't set — verify both HTTP and SSL proxy fields are populated.
10. FAQ
Does this approach work with Selenium 4's new W3C-based capabilities format?
Yes — the underlying proxy object structure is the same across Selenium 3 and 4, though the surrounding capabilities syntax has changed slightly between client library versions.
Can I mix sticky and rotating sessions across nodes in the same grid?
Yes — session type is set per WebDriver session through the username, so different sessions in the same grid can use different modes freely.
How many concurrent sessions can one gateway account support?
This depends on your plan's concurrency limit rather than anything grid-specific — check your dashboard for your account's current concurrent connection limit.