on_conflict policy decides what happens.
Both are set on the trigger request, so each caller says what it needs: a CI pipeline can
cancel the previous run for the same branch, a nightly schedule can wait its turn, and a
one-off run from the dashboard can opt out.
The concurrency object
Omit
concurrency to use the project’s default (see Legacy project setting).
Send "concurrency": null for no limit at all.
on_conflict
The policy belongs to the new run. A
wait run never cancels a running one; a cancel run
always does, even if the running one was itself triggered with wait.
Only runs created in the last 6 hours count as active, so a stuck run cannot block a group
forever.
Choosing a group
Groups are plain strings compared exactly. Include whatever makes two runs “the same thing”
for you, and nothing else.
Scheduled runs
A schedule carries its own block inENVIRONMENTS.yaml:
scheduled_trigger: "0 2 * * *" still works and uses the project default. Configure
scheduled concurrency in ENVIRONMENTS.yaml alongside the cron expression.
The change takes effect only after its pull request is merged into the test repository’s default branch.
What a run records
Every run stores the group and policy it was created with, so the decision stays accurate even if settings change later. It comes back asconcurrency on the run in the API and shows
under Concurrency in the run’s details on the dashboard, where the group links to the list
of all runs in that group. GET /api/test-runs?concurrency_group=<group> filters the list.
concurrency is null when no limit applied.
Reruns reuse the source run’s group and policy.
Legacy project setting
Projects created before per-run concurrency have a project-level setting (test_run_concurrency_limit and test_run_concurrency_behavior) that still applies to any
trigger that omits concurrency. It is frozen: it cannot be changed any more (the API
rejects writes and the dashboard no longer shows it), and it will be removed once callers set
their own blocks. To change how a project’s runs are limited, set concurrency on the trigger
request or scheduled_concurrency on the environment. The frozen scope maps to a group as follows:
/<repo> is present when the run was triggered with a build that names a repository. For branch_environment, a run without build.branch has no group and is not limited.
The legacy behavior independently maps to the conflict policy: