How to limit concurrent workflow runs

I want to use feature like GitLab CI’s resource_group on GitHub Actions

c.f. https://docs.gitlab.com/ee/ci/yaml/#resource_group

1 Like

I also want the native support for limiting concurrent running.

What I want is, when triggered, not only cancelling already running, but also just dequeuing not started ones if present.
Ensuring order of queueing is also important thing around this topic.

Ye this would helo me a lot too

I’ll add my +100 to this. I just don’t understand how GitHub presents Actions as a CI/CD tool when you can’t ensure that a branch can be reliably deployed to a production server, since you will end up with:

  • concurrent deployments if you merge/commit fast enough (and your deploy time takes a few minutes)
  • out of order deployments since in my experience workflows for 2 commits on the same branch are executed in a random order (i.e. an older commit can end up “winning” the deploy over the most recent commit).
3 Likes

we achieved this using actions-mutex.

However, this is rather a poor workaround, because one has to pay for the Action minutes while waiting for the mutex to unlock. This is especially costly when using macos mintues.

I also would like this feature. As it was pointed out, the existing workarounds would just cause wasted minutes. Ability to limit the concurrent workflow runs or a proper queuing mechanism would help a lot.

Hitting the same issue here. Any workflow that commit changes needs this. Currently we have to retry rebase+push over and over again until it goes through.

The feature should be configurable per-branch basis. Master would run in series, rest of the branches in parallel. In optimal case it would also be configurable in a way that it would always build just the latest commit and skip the intermediate ones. So if I’m building commit 1, and in the mean time commits 2 and 3 appears, it would skip commit 2 and directly start building commit 3 after commit 1 build finishes.

1 Like

Adding another +1 for this. Limiting concurrency is a feature I used in Travis, in a prior job. Would be useful to avoid edge-casey confusion in a current build using github actions. :muscle:

I have created an action on exactly the same principle GitHub - robyoung/throttle: A GitHub action for serializing jobs across workflow runs and more with Google Cloud Storage
It automatically unlocks when the job finishes whether it was successful or not.

1 Like

Any news on this? In my particular case, I cannot have 2 workflows running concurrently on my self-hosted machine since the jobs need access to the GPU and if 2 jobs access the GPU then I get a crash.

What’s worse is that I notice if you have 2 workflow A and B, with jobs A-j1/A-j2 and Bj-1/Bj2 then you may end up with the following scenario:

  1. Job A-j1 executes
  2. Job B-j1 executes
  3. Job A-j2 executes

This completely fuck up my workflows flow since both workflows are working with the same $GITHUB_WORKSPACE

2 Likes

In my case I need this because we use Terraform for our AWS infrastructure and two builds can not be running at once, if they do one will fail with Error acquiring the state lock

As previously pointed out by @sue445 this is very easy on GitLab with resource_group

Any official update from the team?
Is this feature on the backlog?

We have recently shipped a feature that will enable you to configure workflow level concurrency for some scenarios GitHub Actions: Limit workflow run or job concurrency - GitHub Changelog.

15 Likes

Hey @chrispat

Is it possible with this new feature to apply the concurrency limit ONLY on the PR level, but not for the pushes to master?

Also, is it possible to have more than 1 pending jobs in the queue? Currently, if another one is queued, the previous one gets canceled. This is problematic for us.

Thanks

You could limit concurrency only in PRs through some trickery with expressions. Because our expressions are truthy something like concurrency: ${{ github.head_ref || concat(github.ref, github.run_number) }} should give you what you want.

At the moment we can’t have more than one in the queue but could you give me an example of your scenario for that?

Hey there,

It would be nice if these examples are provided in the github docs.

At the moment we can’t have more than one in the queue but could you give me an example of your scenario for that?

We do have a few pipelines that send out notification alerts if a pipeline fails or gets canceled. The current behavior is problematic for us, for this reason.

Also, these cancels would cause email alerts from GHA, which is also not ideal.

1 Like

At the moment we can’t have more than one in the queue but could you give me an example of your scenario for that?

Chiming in here: Our example is based on testing. We are severely limited on our hosting partner’s concurrent API calls and only have a single test site.

Therefore, we want to “stagger” the various tests, so they run 1-by-1, all PRs in that concurrency group patiently waiting for the one before it to be done.

That does mean (for example, with dependabot) there could be a PR storm, but they still need to all be processed (not just “the last one”).

4 Likes

Would also be cool if the concurrency had an additional option to skip to the latest job in queue when the first one is finished. Se when job 1 is running, jobs 2 and 3 comes while 1 runs, 2 is skipped when 1 finishes and 3 starts to run. This would speed up the deployment a lot in certain situations.

1 Like

To pile on to this request:

We run tests against some centralized infrastructure resource with each library version we produce (1 commit, 1 version… so a lot). This works fine as long as only 1 test run is active at a time. But as soon as our test framework repository has multiple PRs and updates going at the same time, this of course leads to clashes in usage of that resource.

I was hoping concurrency could help here, which it does for the first additional job. But job 3 will cause the pending job 2 to be cancelled instead.

The solution could be to add a cancelPending: false that just skips the cancellation logic and lets job queue up until the resource is free to be used. We would be very happy to wait as long as needed - there is no way to speed this process up anyway, and re-runnning all jobs in a workflow takes much longer…

1 Like

We have a number of use cases for which this is important, and which we didn’t notice as issues until we increased the speed that we were building & shipping features. In particular:

  1. Some of our legacy e2e test suites require exclusive access to a deployed platform instance. This wasn’t such a big problem before when we moved slower, since they basically only got run manually for big releases. But now we’re moving much faster and we need each run to queue or the test results can be unpredictable.

  2. Most of our services can be deployed independently of one another, but some of our legacy services are deployed all at once, so the deploy job needs to acquire an exclusive lock or strange things happen.

We probably also have some partner API limit considerations like @jasperroel for certain other e2e suites that will crop up as productivity & test rate goes up, although I don’t yet know whether those will be a problem that requires concurrency. In any case, we have problems now.