CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/selenium-grid-4-runner

Author and operate Selenium Grid 4 - self-hosted distributed WebDriver. Covers the six-component architecture (Router / Distributor / Session Map / Event Bus / New Session Queue / Node), standalone vs hub-and-node modes, the Docker-image stack (selenium/standalone-chrome, selenium/hub, selenium/node-chrome), node registration, session-queue tuning, and observability. Use for self-hosted cross-browser testing when data residency or cost-control require an on-prem grid. This is the self-hosted execution RUNNER - for the zero-infra alternative use browser-matrix-runner (Playwright bundled engines); for managed cloud grids use browserstack-automate, saucelabs-automate, or lambdatest-automate; to decide WHICH browsers and tiers to run use browser-matrix-strategy-reference.

75

Quality

94%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files
name:
selenium-grid-4-runner
description:
Author and operate Selenium Grid 4 - self-hosted distributed WebDriver. Covers the six-component architecture (Router / Distributor / Session Map / Event Bus / New Session Queue / Node), standalone vs hub-and-node modes, the Docker-image stack (selenium/standalone-chrome, selenium/hub, selenium/node-chrome), node registration, session-queue tuning, and observability. Use for self-hosted cross-browser testing when data residency or cost-control require an on-prem grid. This is the self-hosted execution RUNNER - for the zero-infra alternative use browser-matrix-runner (Playwright bundled engines); for managed cloud grids use browserstack-automate, saucelabs-automate, or lambdatest-automate; to decide WHICH browsers and tiers to run use browser-matrix-strategy-reference.

selenium-grid-4-runner

Overview

Selenium Grid 4 is the self-hosted distributed WebDriver infrastructure - the open-source alternative to cloud-grid SaaS providers. Per selenium.dev/documentation/grid.

Composes with browser-matrix-strategy-reference for matrix planning.

When to use

  • Data-residency requirements forbid cloud grids.
  • Cost: high-volume testing where cloud per-session pricing exceeds self-hosting break-even.
  • Internal-network apps where tunnel solutions (BrowserStackLocal / Sauce Connect) are insufficient.
  • Custom browser builds / non-standard configurations cloud grids don't support.

For cloud-hosted alternatives see browserstack-automate, saucelabs-automate, lambdatest-automate.

Authoring

Six-component architecture

ComponentRole
RouterEntry point; routes WebDriver requests to the right session
DistributorAllocates new sessions to available Nodes based on capabilities
Session MapTracks active sessions (session ID → Node URL)
Event BusInternal messaging between components
New Session QueueHolds pending session requests when no Node available
NodeRuns actual browser instances; registers with the Distributor

Standalone mode (development / small teams)

All components in one JVM:

# Download from selenium.dev/downloads
java -jar selenium-server-<version>.jar standalone

Default port 4444. WebDriver clients connect to http://localhost:4444/wd/hub.

Standalone mode is suitable for a single developer's machine or a small CI runner with co-located browsers.

Hub-and-node mode (production)

Hub on one machine, Nodes on others:

# Hub
java -jar selenium-server-<version>.jar hub

# Node (on another machine)
java -jar selenium-server-<version>.jar node \
  --hub http://hub-host:4444 \
  --port 5555

For very large deployments each of the six components can run as its own process; see references/distributed-and-ci.md. Most teams run hub-and-node.

Docker stack

Docker images are published as selenium/* on Docker Hub. Pin one Grid version across every image via a single SE_VERSION variable (examples use 4.21.0); keep it identical on the Hub and all Nodes.

# docker-compose.yml   (set SE_VERSION=4.21.0 in .env or the environment)
services:
  selenium-hub:
    image: selenium/hub:${SE_VERSION}
    ports: ["4442:4442", "4443:4443", "4444:4444"]

  chrome:
    image: selenium/node-chrome:${SE_VERSION}
    shm_size: 2gb
    depends_on: [selenium-hub]
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
      - SE_NODE_MAX_SESSIONS=2

  firefox:
    image: selenium/node-firefox:${SE_VERSION}
    shm_size: 2gb
    depends_on: [selenium-hub]
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443

  edge:
    image: selenium/node-edge:${SE_VERSION}
    shm_size: 2gb
    depends_on: [selenium-hub]
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443

shm_size: 2gb is required for Chrome (shared-memory bloat with many tabs).

Standalone Docker (simpler)

docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" \
  selenium/standalone-chrome:${SE_VERSION}

Port 7900 exposes noVNC (browser at http://localhost:7900) for live-session viewing.

Running

Connect a WebDriver client

from selenium import webdriver

driver = webdriver.Remote(
    command_executor="http://grid-router:4444/wd/hub",
    options=webdriver.ChromeOptions(),
)
driver.get("https://example.com")
# ...
driver.quit()

For Kubernetes-deployed Grid use the cluster-internal DNS: http://selenium-router.test-ns.svc.cluster.local:4444/wd/hub.

Capabilities

Standard W3C - no grid-specific options needed:

{
  "browserName": "chrome",
  "browserVersion": "stable",
  "platformName": "linux"
}

Session-queue tuning

Key knobs:

SettingEffect
--session-request-timeoutHow long a queued session waits before failing (default 300s)
--session-retry-intervalPolling interval for matching capabilities (default 5s)
SE_NODE_MAX_SESSIONSMax concurrent sessions per Node (default 1)
SE_NODE_SESSION_TIMEOUTInactive session cleanup (default 300s)

Tune SE_NODE_MAX_SESSIONS per Node's CPU + memory budget; typical: 2 Chrome / 1 Firefox per 2-core / 4 GB Node.

Observability

Grid 4 exposes:

  • GraphQL endpoint at /graphql for session inspection
  • Status endpoint at /status for ready-check
  • Prometheus metrics at /wd/hub/status (Grid health, session counts)

For production add a Grafana dashboard polling Prometheus.

Parsing results

Grid 4 doesn't add session videos / HAR by default - that's the test client's responsibility (or via a sidecar like selenoid + selenoid-ui for Grid 3-style recording).

Logs at /var/log/seluser/ inside Docker containers, exportable via volume mount.

CI integration

Boot the grid, gate on /status ready before running tests, and always tear down. Full GitHub Actions workflow: references/distributed-and-ci.md.

Anti-patterns

Anti-patternWhy it failsFix
shm_size default (64 MB) on Chrome nodeChrome crashes mid-sessionAlways shm_size: "2g"
SE_NODE_MAX_SESSIONS too highOOM / CPU thrashingConservative: 2 per 2-core Node
Hub-and-node without health checkFailed nodes silently drop sessionsWait for /status ready before tests start
Standalone in productionNo HA; single point of failureHub-and-node minimum for prod
Manually allocating ports for NodesConflictsLet Docker assign + use service DNS
No session-queue timeoutSessions wait forever; CI hangsSet --session-request-timeout bounded
Mixing Selenium versions across Hub + NodesCapability negotiation breaksPin same Grid version across all components

Limitations

  • No real-device support out of box. Mobile testing needs Appium server + emulators / real devices - significant additional infrastructure.
  • Browser-version matrix is self-managed. Cloud grids ship 3000+ combinations; self-hosted ≤ what your team builds.
  • HA + scaling is your problem. Cloud grids handle it; on self-hosted you do.
  • macOS / iOS Safari requires actual macOS hosts. Linux can run Chrome / Firefox / Edge but not Safari.

References

Workspace
testland
Visibility
Public
Created
Last updated
Publish Source
GitHub
Badge
testland/selenium-grid-4-runner badge