Skip to main content
Controlling how jobs run in parallel is crucial for production workflows. GitHub Actions’ concurrency key lets you ensure that only one workflow or job in a specified group runs at a time—preventing resource contention, conflicting deployments, or race conditions.

1. Baseline Workflow: Parallel Jobs

Consider a simple workflow with two jobs:
After you trigger this workflow (e.g., via workflow_dispatch), the docker job runs first. The deploy job then spins up the container and sleeps for 600 seconds:
The image shows a GitHub Actions workflow interface with a job sequence involving "docker" and "deploy" steps, currently queued.
Without any concurrency settings, multiple runs will queue up and execute deploy in parallel—often not what you want in production.

2. Introducing concurrency

Use the concurrency key to define a group name and control behavior with cancel-in-progress. Here’s how to cancel any in-progress deploy when a new run starts:
The group value can include {{ github.ref }}, {{ github.sha }}, or environment variables to make it unique per branch or environment. See workflow syntax: concurrency.
When a new run starts, any in-progress deploy in production-deployment is canceled:
The image shows a GitHub Actions workflow summary for "Exploring Variables and Secrets," which was manually triggered and then canceled. It includes details about the "docker" and "deploy" jobs, with annotations indicating errors related to deployment cancellation.

3. Comparing cancel-in-progress Options

4. Queuing New Runs (No Cancellation)

If you’d rather wait for the current deploy to finish, set cancel-in-progress: false:
The second workflow’s deploy job will wait in the Waiting state until the first completes:
The image shows a GitHub Actions interface with a workflow titled "Exploring Variables and Secrets" in progress, specifically highlighting a "Docker Run" step under the "deploy" job.

Watch Video