Skip to content

Cancel superseded CI runs with a concurrency group

This is a principle

A reusable technical claim: something I would want true in any of my work.

Claim. Group CI runs by branch/ref and cancel in-progress runs when a newer commit arrives, so runners aren't spent finishing work on stale commits.

When to apply. Push/PR-triggered pipelines where only the latest commit matters. Not for jobs that must complete once started (deployments mid-flight, release publishing) - there, cancellation can leave partial state.

Why. Without concurrency control, pushing three commits in quick succession launches three full pipelines that all run to completion, wasting minutes and delaying feedback on the commit you actually care about. A concurrency group keyed on the ref cancels the obsolete runs automatically, giving faster feedback and cheaper CI.

Snippet.

concurrency:
  group: deploy_${{ github.head_ref || github.ref_name }}
  cancel-in-progress: true

How enforced. A concurrency block per workflow. Mind the exception above - scope the group so long-running deploys you don't want cancelled use a different (or no) cancellation policy. Pairs with Bound every CI job with an explicit timeout - both stop runners being spent on work that will never usefully finish.

The following pages link to this page: