Operations 5 min read

How to Prevent Jenkins Builds from Interrupting Critical Branches

This article explains how to configure Jenkins pipelines to allow concurrent builds for most branches while ensuring that builds on devel and release branches are queued instead of being aborted, using a simple conditional abortPrevious setting and shared library logic to reduce resource waste and avoid QA disruptions.

DevOps Engineer
DevOps Engineer
DevOps Engineer
How to Prevent Jenkins Builds from Interrupting Critical Branches

Background

In our Jenkins pipelines we often encounter a situation where, if a build for the same branch or PR is already running and a new commit arrives, the current build is automatically aborted and a new build starts.

This is done to control resource usage, especially for long‑running jobs; allowing multiple concurrent builds for the same branch would quickly exhaust Jenkins agents and cause other jobs to wait.

Therefore we usually set the following option in the Jenkinsfile:

<code>// Disable concurrent builds, allow aborting the previous job
disableConcurrentBuilds abortPrevious: true
</code>

This snippet is common in many Jenkinsfiles, even in the Jenkins team's own CI.

The benefit is obvious, but it introduces a new problem: when a release branch build is near completion, a new merge can trigger another build and abort the in‑progress one.

When a build for a release branch is running, a new merge‑triggered build interrupts it, especially if it is about to finish.

This frustrates QA because a build that is about to be delivered for testing gets interrupted and must wait again.

They requested that builds on devel or release branches should not be aborted; new merge‑triggered builds should be queued until the previous one finishes.

Initially I thought the setting was global and could not be differentiated per branch. After searching, I found no simple way to achieve “some branches do not abort but queue”.

Then I came up with a very simple solution: add a conditional check at the start of the pipeline to detect the branch and set the abortPrevious value dynamically.

<code>def call() {
    def isAboutPrevious = true

    if (env.BRANCH_NAME == 'devel' || env.BRANCH_NAME.startsWith('release/')) {
        isAboutPrevious = false // devel and release branches, do not abort
    }

    pipeline {
        options {
            disableConcurrentBuilds abortPrevious: isAboutPrevious
        }
        stages {
            // ... build steps
        }
    }
}
</code>

Result

The logic has been merged into our shared Jenkins library and works as expected after deployment:

✅ Builds on the same devel / release branch are queued, not aborted

✅ Builds for the same PR still abort the previous one, saving resources

✅ No need for separate Jenkinsfiles or complex logic; maintenance cost is minimal

Before the change, the behavior was:

Differences before and after:

Job #104: interrupted before finishing

Job #105: same fate, terminated by new merge‑triggered build

Desired outcome:

Job #106: continues running even if a new merge occurs

Job #107: waits in the queue until #106 completes

Conclusion

If you use Jenkins for multi‑branch builds and need similar branch‑specific behavior, this method is worth trying: a simple conditional statement can control whether a build is aborted or queued.

Feel free to share your Jenkins optimization experiences in the comments!

CI/CDpipelineJenkinsbranchabortPreviousbuild queue
DevOps Engineer
Written by

DevOps Engineer

DevOps engineer, Pythonista and FOSS contributor. Created cpp-linter, commit-check, etc.; contributed to PyPA.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.