To keep an active deployment running, use a shared GitHub Actions concurrency group and leave cancel-in-progress unset or set it to false. One important detail: GitHub’s default pending policy still replaces an older waiting run when a newer one arrives. Add queue: max if you want multiple waiting deployments retained.
Configure deployments without canceling the active run
For example, this workflow serializes deployments to production and keeps up to 100 pending runs in the group:
name: Deploy
on:
push:
branches:
- main
concurrency:
group: production-deploy
queue: max
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- name: Deploy
run: ./deploy.sh
Adapt the trigger, group name, runner, environment, and deployment command to your repository. The key settings are the shared group and queue: max; this example intentionally does not set cancel-in-progress: true. GitHub’s documentation covers concurrency groups and the workflow syntax.
Choose what happens to newer runs waiting to deploy
| Configuration | What happens to the active deployment | What happens to pending runs |
|---|---|---|
Shared group; omit queue or use queue: single; do not enable cancel-in-progress |
It is not canceled by a newer run in the group. | Only one run can wait. A newer run replaces and cancels the existing pending run. |
Shared group; queue: max; do not enable cancel-in-progress |
It is not canceled by a newer run in the group. | Up to 100 runs may wait. Additional runs are canceled when the queue is full. |
These are GitHub’s documented concurrency behaviors. queue: max cannot be combined with cancel-in-progress: true. Pending runs are ordered by when they began waiting, but GitHub warns that this order is not guaranteed to match workflow dispatch order. A queue therefore does not guarantee that deployments execute in strict commit or dispatch order.
#1 Best Overall
Set concurrency at the scope you intend to serialize
Use workflow-level concurrency to serialize whole runs
Place concurrency at the workflow’s top level when each complete workflow run should share one deployment slot. Runs only coordinate when they use the same group, so choose a group name that covers precisely the workflows or runs that must not overlap.
Use job-level concurrency to serialize only deployment work
Place concurrency on the deployment job when other jobs should be able to proceed while that job waits. This avoids making unrelated work wait for the deployment slot. GitHub documents both scopes in its workflow syntax reference.
Check why a deployment is still being canceled or replaced
- An active run is canceled: Check whether the relevant workflow or job has
cancel-in-progress: true. Remove it or set it tofalsewhen active deployments must continue. - A waiting run disappears when a newer one starts: That is the default single-pending behavior. Set
queue: maxif multiple pending deployments should remain queued. - Two deployments overlap: Confirm that both use the same concurrency group at the scope that controls deployment. A group only coordinates the jobs or workflow runs that share it.
- You expected an environment to serialize deployments: An environment name alone does not establish a concurrency group. Environment protection rules and concurrency are separate controls; configure concurrency explicitly. See GitHub’s guide to deploying with environments.
If a run needs to be stopped manually, GitHub documents that separately in its workflow cancellation guide.
Quick Recap
Best Value
Rank #4
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.




