ScreenshotNeo

BlogGuides

Selenium Grid 4 Tutorial: Run Tests Across Browsers in Parallel

Set up Selenium Grid 4, connect Java RemoteWebDriver tests, and run browser sessions in parallel. Choose a topology, size capacity, and troubleshoot common failures.

By the ScreenshotNeo team4 October 202612 min read

Selenium Grid 4 routes WebDriver commands to remote browser instances, letting test suites run across browser versions, operating systems, and machines. To start, run Grid in Standalone mode and point a Java RemoteWebDriver at http://localhost:4444. To get real parallelism, your tests must be independent, Grid must have matching free browser slots, and the machines must have enough resources.

This tutorial starts with a local Grid, then covers Java parallel execution, browser and platform matching, Hub and Node deployment, capacity planning, monitoring, security, and fixes for common errors. The official [Selenium Grid guide](https://www.selenium.dev/documentation/grid/) describes Grid’s role as routing WebDriver scripts to remote browsers.

1. What you need before starting

  • Java 11 or higher on the machine running Selenium Server.
  • The browser or browsers you intend to use on each Grid Node.
  • Browser drivers available on the Node’s PATH, or Selenium Manager enabled for the Grid process.
  • The Selenium Server JAR from the [official Selenium downloads](https://www.selenium.dev/downloads/). Use the current release shown there rather than copying an old version into your setup.
  • A Java test project with Selenium’s Java client dependency. Keep the client and server versions aligned where practical.

Browsers and drivers belong on the machines that run the sessions (the Nodes). The Java client can run elsewhere, provided it can reach the Grid endpoint.

2. Start a local Standalone Grid

Standalone runs the Grid components in one process on one machine. It is the simplest way to learn Grid, debug a RemoteWebDriver test, or run a small CI job.

  1. Download the current Selenium Server JAR and place it in your project or a known tools directory.
  2. Start the server from a terminal. Replace the filename with the release you downloaded:
java -jar selenium-server-<version>.jar standalone

By default, Standalone listens for WebDriver requests on http://localhost:4444. Open that address to view the Grid UI, or request its status:

curl http://localhost:4444/status

If the Grid runs on another machine or in a container, localhost from your test process means the test process’s own host, not the Grid host. Use a reachable hostname or IP for the Grid endpoint.

3. Connect a Java test with RemoteWebDriver

Add Selenium’s Java client to your build. With Gradle, use a pinned Selenium version appropriate for your project; the placeholder below is deliberately a build property, so define it to the version you selected:

// build.gradle
repositories { mavenCentral() }
dependencies {
    testImplementation "org.seleniumhq.selenium:selenium-java:${seleniumVersion}"
}

For Maven, declare org.seleniumhq.selenium:selenium-java with the same pinned version in your pom.xml. This complete Java example creates a remote Chrome session, names it in the Grid UI, visits a page, prints the title, and always closes the session:

import java.net.URI;
import java.time.Duration;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

public class GridSmokeTest {
    public static void main(String[] args) throws Exception {
        String gridUrl = System.getenv().getOrDefault(
            "GRID_URL", "http://localhost:4444");
        ChromeOptions options = new ChromeOptions();
        options.setCapability("se:name", "Grid smoke test");

        WebDriver driver = new RemoteWebDriver(URI.create(gridUrl).toURL(), options);
        try {
            driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(45));
            driver.get("https://example.com");
            System.out.println(driver.getTitle());
        } finally {
            driver.quit();
        }
    }
}

Run it with the Selenium Java client on the classpath and the Grid already running. In a build tool, run it as a test or configure the application plugin to execute its main class. The key connection is the Grid URL passed to RemoteWebDriver; use the Hub or Router address when deploying a multi-machine Grid.

Request a browser or platform

Capabilities describe the session your test needs. Grid’s Distributor matches the request to a free Node slot with compatible capabilities. For example, to request Firefox, create FirefoxOptions; to request a specific browser version or platform, set the corresponding capability:

import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URI;

FirefoxOptions options = new FirefoxOptions();
options.setCapability("browserVersion", "stable");
options.setCapability("platformName", "linux");
options.setCapability("se:name", "Checkout - Firefox Linux");
RemoteWebDriver driver = new RemoteWebDriver(
    URI.create("http://localhost:4444").toURL(), options);
try {
    driver.get("https://example.com");
} finally {
    driver.quit();
}

Use values that match the slots actually registered by your Nodes. A request for an unavailable browser, version, or platform will wait for a matching slot and can eventually time out. Capability matching does not install browsers or create new capacity.

4. Run independent tests concurrently

Grid can serve multiple sessions, but a single sequential test process will still run tests one at a time. Configure your test framework’s parallel mode or use a bounded executor. Each concurrent task needs its own WebDriver instance; never share one driver between threads.

This Java example uses a fixed-size pool and starts one independent Chrome session per URL. Set PARALLELISM to a value Grid and the machines can support:

import java.net.URI;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

public class ParallelGridRun {
    static void checkPage(String gridUrl, String pageUrl) {
        WebDriver driver = null;
        try {
            ChromeOptions options = new ChromeOptions();
            options.setCapability("se:name", "Check " + pageUrl);
            driver = new RemoteWebDriver(URI.create(gridUrl).toURL(), options);
            driver.get(pageUrl);
            System.out.println(pageUrl + " => " + driver.getTitle());
        } catch (Exception e) {
            throw new RuntimeException("Failed: " + pageUrl, e);
        } finally {
            if (driver != null) driver.quit();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        String gridUrl = System.getenv().getOrDefault(
            "GRID_URL", "http://localhost:4444");
        int parallelism = Integer.parseInt(
            System.getenv().getOrDefault("PARALLELISM", "2"));
        var pool = Executors.newFixedThreadPool(parallelism);
        List<String> urls = List.of(
            "https://example.com", "https://www.selenium.dev"
        );
        for (String url : urls) pool.submit(() -> checkPage(gridUrl, url));
        pool.shutdown();
        if (!pool.awaitTermination(5, TimeUnit.MINUTES)) {
            pool.shutdownNow();
            throw new IllegalStateException("Test run exceeded five minutes");
        }
    }
}

This example demonstrates session distribution, not a test assertion strategy. In a real suite, make each task report failures to the test runner, use isolated test data, and size the worker pool to available slots. If you submit more sessions than there are slots, requests queue; they do not make the browsers execute faster.

5. Choose a Grid deployment mode

Mode Where it fits Tradeoffs
Standalone Local development, debugging, small CI jobs on one machine One process and one machine are easy to operate, but it cannot provide browser Nodes on multiple machines.
Hub and Node A shared Grid with a central endpoint and one or more browser machines Supports different OS and browser combinations and lets you add or remove Nodes; requires network connectivity between Hub and Nodes.
Fully distributed Deployments that need each Grid component to run independently Offers separate component placement, with additional deployment, port, configuration, and monitoring work.

Grid 4’s main roles are Router, New Session Queue, Distributor, Node, Session Map, and Event Bus. The Router receives requests and sends new sessions to the queue; the Distributor finds a matching available slot; a Node hosts the browser session. For an existing session, the Router consults the Session Map and routes commands to the Node that owns it. The [official component guide](https://www.selenium.dev/documentation/grid/components/) explains the roles and their interactions.

6. Run a Hub and register Nodes

On the Hub machine, start the Hub:

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

On a Node machine, install Java and the browser(s) and drivers that Node should offer, then register it with the Hub:

java -jar selenium-server-<version>.jar node --hub http://<hub-ip>:4444

When Hub and Node are on different machines, the Node must reach the Hub’s Event Bus ports 4442 and 4443 by default, and the Hub must be able to reach the Node’s HTTP port, 5555 by default. Allow those connections only on the private network paths needed by the Grid. If you changed the Hub’s ports, pass matching --publish-events and --subscribe-events values to the Node, as shown in the [Getting Started guide](https://www.selenium.dev/documentation/grid/getting_started/).

To run two Nodes on one machine, assign separate ports, for example:

java -jar selenium-server-<version>.jar node --port 5555
java -jar selenium-server-<version>.jar node --port 6666

Each Node detects drivers on its system path at startup. Selenium Manager can be enabled for the Grid process with --selenium-manager true; otherwise, make sure the needed drivers are installed and discoverable. Restart or reconfigure Nodes when changing the browsers or drivers they provide.

When fully distributed mode is warranted

In fully distributed mode, start the Event Bus, Session Queue, Session Map, Distributor, Router, and Nodes as separate components, using the addresses and ports from your deployment configuration. The default ports documented by Selenium include Event Bus 4442, 4443, and 5557; Session Queue 5559; Session Map 5556; Distributor 5553; Router 4444; and Node 5555. These defaults can change or conflict with local services, so consult the [current component startup instructions](https://www.selenium.dev/documentation/grid/getting_started/) and [CLI options](https://www.selenium.dev/documentation/grid/configuration/cli_options/) before deploying. Hub and Node covers many shared-grid needs with fewer separately managed parts.

7. Capacity planning and parallel speed

Think of useful concurrency as the minimum of three limits: independent tests ready to run, compatible free Grid slots, and resources available on the machines. Adding threads beyond the slot or resource limit usually increases queueing and contention rather than throughput.

  • Start with a small concurrency value. The Grid documentation gives one concurrent session per CPU as the default Node limit reference (Safari has one slot) and roughly 1 GB RAM per browser session as a planning reference. These are not guarantees; actual use varies by browser, page, test, and host.
  • Measure representative work. Watch session startup time, test duration, CPU, memory, browser crashes, and queue delays in your own CI environment.
  • Use matching capacity. Extra Chrome slots do not help queued Firefox requests. Add browser and platform combinations that tests actually request.
  • Prefer isolation where practical. Smaller Nodes can contain failures and reduce interference, at the cost of more machines and operational overhead.
  • Estimate suite time carefully. Parallel speedup depends on how evenly work divides and whether tests can run independently. Setup time, long tests, shared data, and saturated machines limit gains; do not assume linear speedup.

Grid itself has no software license charge for running the open-source server, but browser infrastructure has compute, memory, storage, network, and maintenance costs. Budget for peak simultaneous sessions and the operating systems or browser versions your coverage requires. No fixed cost or speedup can be stated without your environment and cloud or hardware pricing.

8. Monitor, secure, and keep runs reliable

Check health and available sessions

  • Open the Grid UI at http://<grid-host>:4444 to inspect registered Nodes, slots, and running sessions.
  • Request http://<grid-host>:4444/status for a machine-readable status response.
  • Use se:name in capabilities to label sessions so the UI identifies the test more clearly.
  • Record test failures separately from session-creation failures; a browser that never started points to a different problem than a failed assertion.

Restrict network access

Do not expose Grid endpoints to the public internet. Selenium warns that an exposed Grid can give third parties access to Grid infrastructure and internal applications or files, and may let them run custom binaries. Place the Router or Hub behind private networking and firewall rules, restrict Node and Event Bus ports to the participating machines, and use the security guidance for the Selenium release you deploy. Do not treat an obscure URL as access control.

Improve run reliability

  • Always call quit() in a finally block to release the browser slot when a test finishes or fails.
  • Keep tests independent in browser state and test data; parallelizing tests that mutate shared accounts or records can create flaky failures.
  • Use explicit, bounded timeouts for page loads and waits. Avoid unbounded waits that occupy a scarce slot indefinitely.
  • Retry only failures known to be transient, and capture the original error and session context. Retries can hide product defects or increase load when the Grid is already saturated.
  • Pin browser and driver versions where reproducibility matters, and update them deliberately on the Nodes.

9. Or skip the browser setup

If your task is to capture a page rather than interact with it through WebDriver, [ScreenshotNeo](https://screenshotneo.com) is a website screenshot API and MCP server for developers. One GET request returns an image or PDF; the API accepts parameters used by other screenshot APIs too. See the [ScreenshotNeo API docs](https://screenshotneo.com/docs/) for its options and response details.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo removes cookie banners, popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.

Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.

10. Troubleshooting

Symptom Likely cause Fix
Connection refused at port 4444 Grid is stopped, bound elsewhere, or the client is using the wrong host/port. Check the server process and its startup logs; use the reachable Grid host from the client environment and confirm the configured port.
New session request times out or remains queued No free slot matches requested browser, version, or platform; Nodes are full or unreachable. Inspect the Grid UI and /status, verify Node registration and capabilities, then free or add matching slots.
Could not start a new session: driver or browser missing The browser or driver is absent on the Node, not on the client machine. Install the browser and driver on that Node, put the driver on PATH, or configure Selenium Manager for the server.
Node does not register with Hub Hub address is wrong, Event Bus ports are blocked or mismatched, or the Hub cannot reach the Node port. Check private-network routing and firewall rules for ports 4442, 4443, and the Node HTTP port; ensure custom Event Bus settings match.
Tests appear sequential The test runner is sequential, only one worker is configured, or Grid has one matching slot. Enable framework parallelism or use a bounded worker pool, then confirm multiple compatible free slots and sufficient resources.
Browser processes or slots remain after a failure The test did not call quit(), or the client process ended before cleanup. Place quit() in a finally block; terminate abandoned sessions through your operational process and inspect Node health.
Random failures only under load CPU or memory pressure, shared test data, timing assumptions, or excessive concurrency. Lower worker count, isolate test data, use explicit waits, and measure the Node at representative load before increasing capacity.
Grid UI or endpoint unreachable remotely The service listens on a local interface, firewall blocks traffic, or the client is using localhost incorrectly. Configure a reachable private address and allow only required traffic between trusted systems; keep the service off the public internet.

11. Frequently asked questions

Does Selenium Grid run my tests in parallel automatically?

No. Grid can host concurrent remote sessions, but your test framework or runner must start independent tests concurrently.

Can I use Grid with different operating systems?

Yes. In Hub and Node mode, Nodes can run on different machines and operating systems. Request capabilities that correspond to registered slots.

Can I use Selenium Grid for screenshots?

Yes, WebDriver can take browser screenshots, including screenshots during interactive tests. If you only need a website image or PDF, ScreenshotNeo provides a one-call API and MCP server; see the section above.

Should I choose Hub and Node or fully distributed mode?

Use Hub and Node when you need a shared entry point across browser machines. Choose fully distributed mode when you have a concrete reason to start and operate Grid components separately.

How do I know how many parallel sessions to run?

Start below the available slot limit, then increase concurrency while measuring throughput, queue time, CPU, memory, and failure rates on representative tests.

Source note: Selenium setup commands, prerequisites, default ports, capacity guidance, architecture, and security guidance can change across releases. Check the linked official Selenium documentation when choosing the release and preparing a deployment.