Q: How do you implement workflow concurrency in GitHub Actions, and when should you cancel in-progress runs?
How to configure GitHub Actions concurrency groups: cancelling redundant pull-request builds with cancel-in-progress to save runner minutes, while serializing production deployments to eliminate conflicting releases.
#CI/CD #GitHub Actions #Concurrency #Race Conditions #Cost Optimization #Deployment Safety
🎙️ Candidate Opening & Architectural Context
"I use the concurrency key to prevent duplicate, overlapping runs for the same branch, environment, or deployment target. For pull request CI builds, I set cancel-in-progress: true to terminate stale runs when developers push new commits, conserving runner minutes. For production deployments, I serialize runs using a static environment concurrency group and set cancel-in-progress: false to ensure ongoing releases finish safely without race conditions."
Advertisement
🛠️ Production Runbook & Step-by-Step Resolution
1️⃣
Branch-Level CI Concurrency & Auto-Cancellation
Save CI runner minutes and reduce queue congestion during rapid pull request iterations:
# Branch-level CI concurrency configuration
name: CI Pipeline
on:
pull_request:
branches: [main]
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
- Dynamic Concurrency Group: Combine the workflow name and git branch reference (
github.workflowandgithub.ref) to scope concurrency per PR. - Cancel In-Progress: Setting
cancel-in-progress: trueautomatically aborts the currently running job as soon as a new push occurs on the same branch. - Cost Optimization: Eliminates runner waste by not testing obsolete commits that have already been superseded.
2️⃣
Production Deployment Serialization & Safety
Prevent simultaneous deployments from conflicting over state locks, database migrations, or cloud resources:
# Environment-level deployment concurrency (Mutual Exclusion)
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
concurrency:
group: deploy-production-api
cancel-in-progress: false
steps:
- uses: actions/checkout@v4
- name: Deploy application
run: ./deploy.sh production
- Static Environment Group: Group deployments by target environment name (e.g.
deploy-production-api). - Queue Without Aborting: Set
cancel-in-progress: falseso that if two merges happen back-to-back, the second deployment waits in queue until the first completes successfully. - Job-Level Concurrency: Apply concurrency at the individual job level rather than the entire workflow if only the deploy phase requires mutual exclusion.
💡 The Senior SRE Gold Nugget (Key Architectural Takeaway)
"Use cancel-in-progress: true for pull requests to cancel obsolete builds and save runner costs. Use cancel-in-progress: false with static environment groups for production to serialize releases safely."
⚡ 60-Second Elevator Pitch Talking Points
- Apply concurrency groups using github.workflow and github.ref to isolate concurrency scopes.
- Cancel superseded pull-request builds with cancel-in-progress: true to optimize runner utilization and reduce queue times.
- Serialize production deployments with cancel-in-progress: false to prevent race conditions and conflicting releases.
Advertisement