skip to content

Why can raising SE_NODE_MAX_SESSIONS on a Selenium node container leave its concurrency unchanged?

level: middleimportance: should knowfreq 42%

answer

  1. Compare what you set with what runs
  2. The node counts something at start-up
  3. One variable alone is not enough
  4. Available processors form the ceiling
  5. SE_NODE_OVERRIDE_MAX_SESSIONS must be true

basics

~20 s

Selenium's Node caps its session count at the processors it detects, so a larger SE_NODE_MAX_SESSIONS is silently reduced. The higher number applies only when SE_NODE_OVERRIDE_MAX_SESSIONS is also true and the container really has that CPU.

solid answer

~40 s

In Selenium 4 the node images write `SE_NODE_MAX_SESSIONS` into the `max-sessions` key of a `config.toml` they generate at start-up, and the Grid's `NodeOptions` then clamps it: the Node keeps the smaller of the configured value and the processor count it detects, unless `override-max-sessions` is `true`. Because the images default `SE_NODE_MAX_SESSIONS` to `1` and `SE_NODE_OVERRIDE_MAX_SESSIONS` to `false`, a `selenium/node-chrome` container pinned to two processors and asked for four sessions still registers two slots, and the extra loan-renewal cases queue instead of running. Nothing errors — the number is accepted and quietly reduced. The fix is to give the container real CPU and then set both variables together, remembering that more sessions per container also means dividing the same `--shm-size` allocation and RAM among them.

code

bash · 6 lines
bash
docker run -d --net grid \
  -e SE_EVENT_BUS_HOST=selenium-hub \
  -e SE_NODE_MAX_SESSIONS=3 \
  -e SE_NODE_OVERRIDE_MAX_SESSIONS=true \
  --cpus=3 --shm-size="2g" \
  selenium/node-chrome:4.48.0-20260905

go deeper

for a junior

Be ready to say that a Selenium browser node container serves one session by default and that more sessions need an explicit setting. Knowing the variable name SE_NODE_MAX_SESSIONS is enough at this stage.

for a middle

Explain the clamp: the Node compares the requested count with the processors it detects and keeps the smaller one unless the override variable is set. Name both variables and say which one unlocks the other.

for a senior

Show how you would diagnose this on a running fleet. Read the node container's start-up log for the detected processor count, compare it with the CPU the container was actually given, and only then change a number.

for a principal

Own the tradeoff. Argue when packing several sessions into one container is worth the shared /dev/shm, the shared CPU and the lost isolation, against simply running more single-session containers instead.

## The variable is a shorthand, not a switch Selenium 4's browser node images — `selenium/node-chrome`, `selenium/node-firefox`, `selenium/node-edge` and the `selenium/standalone-*` family — do not consume `SE_NODE_MAX_SESSIONS` directly. A start-up script inside the container generates a `config.toml` and hands that file to the Grid **Node** process, so the environment variable is really a way of filling in one line of a generated file: ```toml [node] override-max-sessions = false max-sessions = 4 ``` The images ship their own defaults of `SE_NODE_MAX_SESSIONS="1"` and `SE_NODE_OVERRIDE_MAX_SESSIONS="false"`, which is why an untouched browser node container serves exactly one session at a time. Setting the first variable changes the generated line; it does not, on its own, change what the Node decides to advertise. ## Where the number gets clamped `NodeOptions`, the Grid class that reads that configuration, defines its default maximum as the number of processors the JVM inside the container reports. When it resolves the setting it keeps the **smaller** of two numbers — the value you configured and that detected processor count — and returns your larger number only when `override-max-sessions` is `true`. For a container given two processors and asked for four sessions, the sequence runs: 1. The image writes `max-sessions = 4` into the generated `config.toml`. 2. The Node detects two available processors and logs that count as it starts. 3. `override-max-sessions` is `false`, so the Node keeps the minimum of four and two and registers **two** slots. 4. The extra loan-renewal cases you fired at the grid wait for a free slot instead of starting. Nothing fails. The number you set is accepted, written to the file, read back — and then quietly reduced. That silence is the whole reason this question gets asked: the symptom is a suite that will not go faster, not an error message. ## The two variables side by side | Environment variable | Node config key | Image default | What it controls | |---|---|---|---| | `SE_NODE_MAX_SESSIONS` | `max-sessions` | `1` | How many concurrent sessions the node is asked to offer | | `SE_NODE_OVERRIDE_MAX_SESSIONS` | `override-max-sessions` | `false` | Whether that request may exceed the detected processor count | Both are ordinary container environment variables — there is no separate flag, no restart hook and no grid-side setting that lifts the ceiling from outside the node. ## Why the ceiling exists at all - A **real browser** is running in that container: renderer processes, a GPU process, a network stack. It is not a lightweight worker you can multiply for free. - Selenium's guidance is **one browser session per available processor**, which is precisely why the detected processor count was chosen as the default and the ceiling. - When you do switch the override on, the Node logs a warning that the recommended concurrency is being exceeded and that session stability and reliability may suffer. That warning is the project telling you this is an exception, not a tuning knob. - The processor count the Node sees is the container's view, not the host's. Giving a container a fractional or single-CPU allocation and then asking for four sessions is asking for a number the container was never issued. ## Raising it honestly 1. **Give the container the processors first.** Whole processors, one per intended session, before you touch either variable. 2. **Set both variables in the same change** — `SE_NODE_MAX_SESSIONS` to the number you want and `SE_NODE_OVERRIDE_MAX_SESSIONS=true` — because setting only the first is the failure this question is about. 3. **Raise the shared-memory allocation with it.** Several browsers in one container divide the same `/dev/shm`, so a `--shm-size` that was comfortable for one session may not be for three. 4. **Confirm what the node actually registered** rather than what you asked for; the start-up log records the processor count it detected. ## What a second session in the same container costs - **Shared memory** and **RAM** are per container, so every extra session shrinks what each browser has. - **CPU contention** shows up as slower page loads on the loan-renewal form, which reads as a flaky wait rather than as a capacity decision you made. - The `selenium/video` recorder follows a container's display, so Selenium documents an undesired side effect: with more than one session per container, several sessions can end up captured in the same video file. - **Blast radius** grows. A container that dies takes every session inside it, not one. The honest summary is that `SE_NODE_MAX_SESSIONS` alone is a request, `SE_NODE_OVERRIDE_MAX_SESSIONS` is the permission, and processors are the thing that makes either of them real.

  • Where does a node container's session setting actually end up?
    The image's start-up script generates a `config.toml` inside the container with a `[node]` section, writing `max-sessions` from `SE_NODE_MAX_SESSIONS` and `override-max-sessions` from `SE_NODE_OVERRIDE_MAX_SESSIONS`. The environment variables are a shorthand for lines in that generated file, not a separate mechanism the Node consults at runtime.
  • What breaks first when you push sessions per container too high?
    Shared memory and RAM. Several browsers in one container divide the same `/dev/shm`, so the size you passed with `--shm-size` is split and pages start failing to render or the browser dies outright. CPU contention shows up next as slower page loads, which read as flaky waits rather than as a capacity decision.
  • Why does the recommendation stop at one session per processor?
    A real browser is CPU-hungry, so Selenium treats one session per available processor as the safe ratio and makes the detected processor count the default ceiling. The Node logs a warning when the override is enabled, saying stability and reliability may suffer — above that ratio you trade predictable sessions for a bigger number.

saying these in an interview costs you the question

  • Says SE_NODE_MAX_SESSIONS alone lifts a node container to any number
  • Thinks a browser node container runs unlimited sessions by default
  • Confuses sessions per container with the suite's own thread count
  • Assumes headless browsers are cheap enough to ignore CPU limits
  • Raises the session count without adding CPU or shared memory