How to Prevent Split Batches in Parallel Applitools Tests
Give every worker and shard in one Applitools test run the same unique batch ID. Here are environment-based and SDK-based setups, CI examples, and fixes for common causes of split batches.
Give every worker and shard in a single intended Applitools test run the same batch ID. A reliable way to do that is to generate one fresh ID at the start of the run, set APPLITOOLS_BATCH_ID before starting the tests, and make sure every process receives that value. Give separate runs different IDs so unrelated results do not merge.
Applitools batches group related test results in a common dashboard container. Parallel workers often run in separate processes, and those processes do not share ordinary in-memory state. If each worker creates a batch without an explicit shared ID, the workers can end up with separate batches. Applitools’ glossary describes batches, and its parallel Playwright guide demonstrates the environment variable approach.
Set one batch ID before starting the run
Generate the ID once in the process that starts the test run, then export it before invoking the runner. For example, in a POSIX shell:
export APPLITOOLS_BATCH_ID="$(python -c 'import uuid; print(uuid.uuid4())')"
npx playwright test
This example creates a new UUID for this invocation and passes it through the environment to the test process and its workers. The Python command is used only to generate an ID; it does not configure Applitools itself. If your runner starts remote workers or separate CI jobs, setting the variable in the parent shell alone is insufficient unless the runner or CI system forwards the same value to those jobs.
You can also generate a value in Node.js and start a child process with that value:
import { randomUUID } from 'node:crypto';
import { spawn } from 'node:child_process';
const batchId = randomUUID();
const child = spawn('npx', ['playwright', 'test'], {
stdio: 'inherit',
env: { ...process.env, APPLITOOLS_BATCH_ID: batchId },
});
child.on('exit', (code) => {
process.exitCode = code ?? 1;
});
Use the same generated value for every shard that belongs to the run. Generate a different value for a separate run, including a concurrent run on the same branch. Applitools recommends unique IDs to prevent irrelevant tests from being grouped together; its batching documentation describes UUIDs as a suitable choice.
Configure CI shards and matrix jobs
When CI divides tests across jobs, have the workflow create or receive one run ID and expose it to every participating job. The value must be stable across shards for one run, yet different between independent runs. Do not generate a new random ID independently inside each shard: that recreates the split.
One common pattern is to use a unique CI workflow run identifier if your provider exposes one to every shard. Another is to generate a UUID in an orchestration step, publish it as a shared output, and pass that output into each job. The exact syntax depends on the CI provider; the required behavior is the same: all participating jobs receive an identical APPLITOOLS_BATCH_ID. Applitools’ Storybook scaling guide illustrates a commit-derived value for a sharded workflow. A commit value can be reused by later runs on the same commit, so prefer a per-run identifier when separate executions must remain distinct.
# Conceptual shell step; CI-specific output wiring is omitted.
export APPLITOOLS_BATCH_ID="$SHARED_RUN_BATCH_ID"
npx playwright test
Check these points when wiring a pipeline:
- Create or choose the ID once per intended batch, outside the individual shard processes.
- Pass that exact value to every matrix job or shard that should appear together.
- Forward the variable into containers and remote workers explicitly when the CI runner does not inherit it automatically.
- Keep concurrent workflow runs isolated with different IDs.
- Give the batch a useful name for dashboard readers where your SDK or runner configuration supports it. The ID groups results; the name helps people recognize the run.
Alternative: set the ID on BatchInfo
You can configure the batch ID in code through the SDK’s BatchInfo object instead of using a process environment variable. This is useful when configuration belongs with your test setup. It still needs to be set to the same value in every worker before tests are opened. The SDK batching page has examples for several languages; use the syntax for your installed SDK version.
// JavaScript example; adapt imports and setup to the installed SDK version.
const batch = new BatchInfo('Parallel CI run');
batch.setId(process.env.APPLITOOLS_BATCH_ID);
// Apply this batch to the Eyes instance before opening the test.
eyes.setBatch(batch);
The example shows the configuration shape, not a complete test fixture: class imports and lifecycle calls differ across SDKs and versions. If you choose this approach, establish the shared ID in the CI environment or another run coordinator, then assign it to each worker’s BatchInfo. Avoid generating an ID inside each worker’s setup.
Environment variable or SDK configuration?
| Approach | Configuration lives in | Best fit | Key requirement |
|---|---|---|---|
APPLITOOLS_BATCH_ID |
Shell, CI, container, or process environment | Runs spread across processes, machines, or shards | Every process receives the same value |
BatchInfo ID |
Test setup code | Teams that centralize Applitools setup in code | Every worker assigns the same ID before opening tests |
Both patterns solve the grouping problem only if the effective ID matches across workers. Environment injection can be convenient for distributed runs because the coordinator can distribute one value to every worker. That is an implementation inference from the documented configuration patterns, not a guarantee about every runner or CI provider.
What to check when batches still split
- Compare the effective values. Inspect the environment inside each worker or shard at test startup. Confirm the variable is present and identical, without logging secrets or unrelated environment values.
- Check container forwarding. A variable set on the CI host may not be passed into a container. Add it to the container’s environment configuration and verify it inside the test process.
- Look for per-worker ID generation. If each worker runs a UUID generator, each worker gets a different batch. Generate once in the coordinator instead.
- Check SDK setup timing. If using
BatchInfo, assign the shared ID before opening tests, and make sure every worker uses the same value. - Separate concurrent runs. Reusing a static ID can combine unrelated results. Give each independent run its own ID.
- Review runner and SDK configuration. If the values match but results still split, inspect the effective configuration and version-specific behavior. Applitools’ cited material does not establish a universal compatibility matrix for every runner and SDK combination.
Performance, reliability, and cost considerations
A batch ID is a grouping setting; it does not make tests execute faster or reduce the work of capturing and comparing pages. Its reliability depends on generating the value once, distributing it correctly, and avoiding accidental reuse across independent runs. Prefer a run-scoped UUID or another run-unique identifier over a fixed string or a commit-only value when repeated executions of the same commit should remain separate.
The research sources describe how IDs group results but do not provide pricing or cost figures for Applitools. Check your Applitools plan and usage terms for current billing details. Do not treat a shared batch ID as a way to change test execution or billing semantics.
Or skip the browser setup
For a website screenshot outside the Applitools test-run grouping problem, ScreenshotNeo is a screenshot API and MCP server for developers. It is an alternative to try first when you need a clean page capture: it removes cookie banners, newsletter popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed; and its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots per month with no card, and paid plans start at $5 for 3,000. See the API documentation.
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}`);
Replace the example URL with the page you want to capture and supply your API key. See the ScreenshotNeo docs for request options. Create a free account for 1,000 screenshots a month, with no card required.
FAQ
Does every test in one batch have to run in the same process?
No. The purpose of sharing the batch ID is to group results that can come from separate workers or machines.
Should I use a commit hash as the batch ID?
It can group shards for a commit, as in Applitools’ Storybook example. If repeated runs on the same commit should be distinct, use a value unique to each run instead.
Does the batch name control grouping?
The ID is the grouping value. The name is a human-readable label for identifying the batch.
Can I set both the environment variable and BatchInfo?
You can configure the ID through either documented pattern. If both are used, make sure the value applied by the SDK is consistent with the shared run ID and verify behavior for your installed SDK version.
Will a shared ID merge results from separate runs?
It can. Give each independent run a new ID to avoid grouping unrelated test results.


