Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild
Back to Blog Explainer

Execute Concurrent Builds If Necessary: What That Checkbox Actually Does

Sean

Platform Writer

Aug 08, 2026
8 min read

Execute concurrent builds if necessary is a Jenkins job setting that allows more than one build of the same job to run at the same time. Without it, a second trigger queues behind the first. With it, both run in parallel — which is exactly what you want for a parametrised job and exactly what breaks a job that writes to a shared location.

Execute Concurrent Builds If Necessary: What That Checkbox Actually Does

The setting appears on freestyle projects. Pipeline jobs handle concurrency differently, which is a source of confusion when someone goes looking for the checkbox and cannot find it. Either way, the decision underneath is the same, and it comes down to one question about your job.

Table of contents

The default, and why it exists

By default a Jenkins job runs one build at a time. Trigger it while a build is running and the new one waits in the queue until the current one finishes.

That default is conservative on purpose. Serial execution guarantees a set of properties that a lot of build scripts quietly depend on:

  • The workspace directory contains exactly what the previous build left, and nothing is modifying it underneath you.
  • Any file the build writes — an artifact, a report, a lock file — has one writer.
  • External resources the build touches, like a shared test database or a deployment target, see one build at a time.
  • Build numbers complete in order, so the highest-numbered finished build is the newest.

Enabling concurrency removes all four guarantees at once. That is fine if your job never needed them, and a source of very confusing intermittent failures if it did.

What changes when you enable it

The most visible change is the workspace. Jenkins cannot give two simultaneous builds the same directory, so it creates additional ones — typically the job’s workspace with a suffix appended, like myjob@2.

That has consequences people hit immediately:

  • Anything with a hardcoded workspace path breaks. A script referencing /var/lib/jenkins/workspace/myjob directly will find itself in the wrong directory half the time.
  • Disk usage multiplies. Three concurrent builds of a job with a 5GB checkout is 15GB of workspace.
  • Build caches stop being shared. Each workspace has its own dependency cache, so the first build in each new workspace is slow.
  • Cleanup gets harder. Extra workspaces accumulate and are not always removed.

None of these is fatal. All of them are surprising the first time, and the disk one has taken down build servers.

When to turn it on

The clear case is a parametrised job that is really N independent jobs wearing one configuration.

A job that takes a target environment as a parameter, or a test suite that takes a browser name, or a deploy job that takes a region — those runs have nothing to do with each other. Making them queue behind one another is pure waste, and the queue gets worse the more parameters you add.

The other good case is a job triggered per pull request. Ten open PRs should not mean a ten-deep queue where the last developer waits an hour for feedback on a one-line change. Concurrency here is the difference between CI being useful and CI being something people work around.

The shared property in both: each run operates on different inputs and writes to different outputs. Nothing they touch is shared.

When to leave it off

Leave it off — or gate it — when runs share anything mutable:

  • A deployment target. Two builds deploying to the same environment simultaneously produce whichever result finishes last, and possibly a mixture. This is the one that causes real incidents.
  • A shared test database. One build’s migrations or fixtures wipe the other’s data mid-run, producing failures that never reproduce.
  • A version counter or release tag. Two builds incrementing the same number race.
  • Any external system with a single lock, like an app store submission or an infrastructure state file. Terraform state is the classic example — concurrent applies against the same state are how state files get corrupted.

The Terraform case is worth calling out because it is common and the damage is durable. Two concurrent applies against a state file without locking can leave the state inconsistent with reality, and reconciling that by hand is genuinely painful.

Concurrency with a lock, which is usually what you want

Most jobs are not purely parallel or purely serial. They have a long parallel phase — checkout, build, test — and a short serial phase, usually the deploy.

Forcing the whole job serial to protect the deploy step wastes the parallel phase. The better shape is to allow concurrency and lock only the part that needs it. In a pipeline, that is what the lock step does:

stage('Build') {
    steps { sh './build.sh' }        // runs concurrently
}
stage('Deploy') {
    options { lock('staging-environment') }
    steps { sh './deploy.sh staging' }  // one at a time
}

Builds and tests run in parallel across every triggered run; deploys serialise on the named resource. This gets you the throughput without the race.

For freestyle jobs, the equivalent is the Throttle Concurrent Builds plugin, which can cap concurrency per node or globally and can group several jobs under a shared limit — useful when three different jobs all deploy to the same place.

Why pipeline jobs do not show the checkbox

The checkbox is a freestyle-project setting. Pipeline jobs invert the default: they allow concurrent builds unless told otherwise, and the control lives in the pipeline definition rather than in the job configuration UI.

To disable it:

options {
    disableConcurrentBuilds()
}

Or, more usefully for a job triggered repeatedly on the same branch, cancel the superseded run instead of queuing it:

options {
    disableConcurrentBuilds(abortPrevious: true)
}

That second form is the right default for pull-request builds. If someone pushes three commits in five minutes, testing the first two is wasted work — the only result anyone cares about is the newest. Aborting the previous run frees an executor and gets feedback on the current commit sooner.

The general principle worth carrying: concurrency settings are about which runs are worth doing, not just how many can run at once. A queued build of stale code has negative value — it consumes an executor to produce an answer nobody will read.

How this fits the rest of the stack

Build concurrency is one of those settings where the right answer depends entirely on what the job touches, and the wrong answer shows up as intermittent failures that never reproduce locally. The same question applies to deploys generally: two deploys landing at once is a race whether a CI server or a person started them. Deploying from a repository with a visible build log and deploy history at least makes the sequence readable after the fact — Builds on RunxBuild covers how a build becomes a live route. If you are working out the cost of the services and databases a pipeline deploys to, the RunxBuild hosting calculator itemises them.

Useful related references:

FAQ

What does execute concurrent builds if necessary do?

It allows more than one build of the same Jenkins job to run simultaneously instead of queuing. Jenkins creates additional workspace directories with numbered suffixes so each concurrent build has its own working directory.

Why can I not find the checkbox on my pipeline job?

It is a freestyle-project setting. Pipeline jobs allow concurrent builds by default and are controlled from the pipeline definition using options { disableConcurrentBuilds() } instead.

Is it safe to enable concurrent builds?

Safe when each run uses different inputs and writes to different outputs — parametrised jobs and per-pull-request builds. Unsafe when runs share a deployment target, a test database, a version counter, or a Terraform state file.

How do I allow concurrency but serialise deploys?

Use the lock step around only the deploy stage. Builds and tests run in parallel while deploys serialise on a named resource. For freestyle jobs the Throttle Concurrent Builds plugin does the equivalent.

What happens to the workspace with concurrent builds?

Jenkins creates additional workspace directories with an @2, @3 suffix. Scripts with hardcoded workspace paths break, disk usage multiplies, and dependency caches are no longer shared between builds.

#execute concurrent builds if necessary#jenkins#ci/cd#build pipeline#workspace