The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Use GitHub Actions’ concurrency setting to limit overlapping workflow runs or jobs that share a group key. The key decision is what to do with newer work: by default, it replaces an older pending run; add cancel-in-progress: true to cancel the active run too, or use queue: max when runs should wait their turn.
What concurrency groups do
GitHub Actions allows workflow runs to execute concurrently unless you configure otherwise. A concurrency group lets matching workflow runs or jobs share a limit: only one can be active in that group at a time. Put the setting at workflow level to control whole runs, or under a job to limit only that job. GitHub documents both scopes and their behavior.
Concurrency is not a guarantee that every triggered run will eventually execute. By default, a group can have one active run and one pending run. When another run arrives, it replaces the older pending run. The active run continues unless you enable cancellation.
Choose a group key that matches what must not overlap
The group key defines which work shares the concurrency limit. GitHub’s documented pattern for controlling runs of the same workflow on the same branch or tag is:
#1 Best Overall
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
Including github.workflow keeps separate workflows from unintentionally sharing the same group. Group names are case-insensitive, so keys that differ only in capitalization are treated as the same group. See GitHub’s concurrency documentation.
Pull requests and mixed triggers
github.head_ref identifies a pull request’s source branch, but it is defined only for pull_request events. If a workflow also runs for other event types, GitHub shows this pattern to provide a fallback:
concurrency:
group: ${{ github.head_ref || github.run_id }}
The fallback run ID gives non-pull-request events distinct groups; it does not group those events together by branch. Choose a fallback that matches the policy you want. If you use github.ref for pull requests, it may identify the PR merge ref rather than the source branch.
Shared resources and matrix jobs
If the goal is to protect a shared resource, such as a deployment target, make the group key identify that resource. Include workflow identity if workflows should not cancel or block one another. Decide deliberately whether to include matrix values: omitting them makes matching matrix jobs share a group, while including them lets separate matrix values proceed independently. GitHub permits matrix values in job concurrency expressions.
Choose whether newer work replaces, cancels, or queues
| Policy | What happens | Use it when |
|---|---|---|
| Default | One run is active; a new run replaces the older pending run. The active run is not canceled. | Only the newest waiting run matters, such as repeat CI checks after successive pushes. |
cancel-in-progress: true |
A new run cancels the active run in the same group, as well as replacing any older pending run. | Newer work makes active work expendable, such as tests for an outdated commit. |
queue: max |
Runs wait in a queue, with up to 100 pending workflow or job runs. | Each run should get a chance to execute rather than being replaced while pending. |
GitHub says queue order is based on when a run started waiting, not when it was dispatched, and ordering is not guaranteed. Therefore, queue: max is not a strict arrival-order guarantee. It also cannot be combined with cancel-in-progress: true. Check GitHub’s current concurrency rules.
Example: cancel stale CI runs for the same ref
This illustrative workflow applies the concurrency rule to whole runs. Adapt its triggers and test command to your repository.
name: CI
on:
push:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
With this setting, a newer run for the same workflow and ref cancels the active run in that group. If your intended policy is to group pull requests by their source branch instead, use github.head_ref and provide a fallback when the workflow handles events where that value is unavailable.
When to use job-level concurrency instead
Use workflow-level concurrency when the whole run must share a limit. Use jobs.<job_id>.concurrency when only one job needs serialization—for example, a deployment job that must not overlap while unrelated checks can continue. The group key still determines which runs or jobs interact, and the pending and cancellation policy still matters.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteQuick Recap
Best Value
Limits to keep in mind
- Cancellation can interrupt active work. Review its effects before enabling it for deployments or any operation that may be unsafe to stop midway.
- Concurrency groups govern matching work in the repository; the documented feature does not establish a cross-repository lock or an exactly-once guarantee for external side effects.
- Different workflows using the same group string can interfere. Include workflow identity unless sharing a group is intentional.
- The queue supports up to 100 pending runs and does not promise dispatch-time ordering.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




