Skip to content

Your CI Is Running Tests on Old Code: How to Auto-Cancel GitHub Actions

Here’s a scenario you’ve probably experienced: You push a commit to your pull request and GitHub Actions starts running your tests. Two minutes later, you spot a typo and push another commit. Now you have two test runs executing in parallel—one testing code you’ve already replaced.

By default, GitHub Actions doesn’t cancel old runs when you push new commits. If you’re iterating quickly during development, you might have 3-4 runs stacking up, all testing outdated code. You’re paying for all of them.

The Fix: Three Lines of YAML

Add this to the top of your workflow file, right after the on: section:

name: Tests

on:
  pull_request:

# Add these 3 lines:
concurrency:
  group: ${ { github.workflow } } -${ { github.event.pull_request.number || github.ref } }
  cancel-in-progress: true

jobs:
  test:
    # ... your existing jobs

What This Does

The concurrency configuration creates a group for your workflow runs. When a new commit arrives:

  1. GitHub checks if another run is already in progress for this PR
  2. If yes, it cancels the old run
  3. Only the most recent run continues

'GitHub actions cancel in progress diagram

Why the group Key Looks Like That

group: ${ { github.workflow } } -${ { github.event.pull_request.number || github.ref } }

This creates a unique group for each PR by combining:

Time = Money

Before adding this, I could have 3-4 test runs executing in parallel during active development. Each run took ~10-15 minutes. That’s ~45 minutes of Actions time where only the last 15 minutes actually mattered.

After adding concurrency cancelation: only one run at a time. Immediate savings.

When You Shouldn’t Use This

There are a few cases where you might not want automatic cancelation:

Copy-Paste Template

name: Tests

on:
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Run tests
        uses:  actions/checkout@v4
        run: npm test

This is the easiest GitHub Actions optimization you can make. Three lines of configuration, zero complexity, immediate savings on your GitHub Actions bill.


Previous Post
Shared Brain: Achieving Zero-Wait States with Optimistic UI
Next Post
Per-User JWT Secrets: Enterprise-Grade Token Revocation for External Clients in Wasp