Connecting to a Grid is one line. Owning one is infrastructure work, and at senior level in a Selenium organisation it is often your responsibility.
The components, in the modern architecture. Grid 4 splits what used to be a hub into named parts, and knowing them matters when you are diagnosing a stuck queue:
Router receives all requests and forwards them. Distributor decides which node runs a session and creates it. Session Map remembers which node holds which session. Session Queue holds requests waiting for a free slot. Node runs browsers.
For small setups these run together in one process (standalone). At scale they are separated so each can be scaled independently.
Capacity planning, which is the actual senior question.
Start with what you need, not with what you can afford.
How many concurrent sessions? If a suite of 2,000 tests averaging 10 seconds must finish in 15 minutes, you need roughly 2,000 × 10 / 900 = 23 concurrent sessions. Round up for overhead: 30.
How many nodes? A node's capacity is bounded by memory, not by configuration. A browser session needs roughly 1GB in practice. A 16GB node comfortably runs 8 to 10 sessions, not the 16 the arithmetic suggests, because the operating system and the node process need room.
So 30 sessions is 3 to 4 nodes of that size.
Do not oversubscribe. Configuring 20 sessions on a 16GB node produces swapping, and swapping makes every session slow, which trips timeouts across the whole suite. The symptom looks like widespread flakiness and the cause is capacity. This is one of the most common misdiagnoses in Selenium infrastructure.
Docker is the standard deployment now.
services:
selenium-hub:
image: selenium/hub:latest
ports: ["4444:4444"]
chrome:
image: selenium/node-chrome:latest
shm_size: 2gb
depends_on: [selenium-hub]
environment:
SE_EVENT_BUS_HOST: selenium-hub
SE_NODE_MAX_SESSIONS: 4
shm_size: 2gb is not optional. Chrome uses shared memory, and Docker's 64MB default causes crashes that look exactly like random test failures. This single line resolves a class of "Grid is unreliable" complaints, and it is the first thing to check when someone reports one.
Ephemeral nodes. Some teams run one browser per container and discard the container after each session. Slower to start, and it guarantees a clean browser every time, which eliminates a whole category of state-leak problems. Worth the cost on suites where cleanliness matters more than latency.
Autoscaling. Grid can scale node counts on demand in Kubernetes. Useful when load is bursty, which is typical: nothing overnight, heavy at merge time. It also adds operational complexity, so it is worth doing when idle capacity is actually expensive rather than by default.
Health and observability. A Grid nobody monitors fails silently. Three things to watch: queue depth (rising means insufficient capacity), session duration (rising means contention or a slow application), and node availability (a node that dropped out reduces capacity without any error appearing in your test output).
Grid exposes a status endpoint and can export metrics. Wire them into whatever dashboard your organisation already uses, because a Grid problem that presents as flaky tests will otherwise be investigated as a test problem for days.
Self-hosted or cloud? The honest comparison. Self-hosting is cheaper per session at steady high volume and costs you maintenance, upgrades and on-call. Cloud providers cost more per session and remove all of that, plus they give you real devices and browser versions you cannot easily run yourself.
Most organisations should start on a cloud provider and move to self-hosting only when volume makes the cost difference clearly outweigh the operational burden. Teams that self-host too early spend their senior engineer's time on infrastructure rather than on testing.
Remember this: size by concurrent sessions and memory, never oversubscribe, set shm_size, and monitor queue depth.
Reference: Grid components.