jobs: lint: runs-on: ubuntu-latest steps: - run: pnpm lint typecheck: runs-on: ubuntu-latest steps: - run: pnpm typecheck unit: runs-on: ubuntu-latest steps: - run: pnpm testThree jobs, and each one boots its own runner, clones the repo, restores its cache, then runs a single command. You split lint, type-check, and unit tests this way because you wanted them to run at the same time, and separate jobs were the one way GitHub Actions ran work in parallel. GitHub put native parallel steps on its Q2 2026 roadmap as the most-requested Actions feature and committed to ship before July. Steps inside one job will run concurrently, sharing that job’s filesystem and environment.
The runner-startup and artifact tax
Each job in that file pays a fixed cost before it touches your code. GitHub spins up a fresh runner, around 25 seconds, then the job checks out the repo and restores its cache. Three concurrent jobs charge you that startup three times over. GitHub’s own Actions retrospective names runner queue and startup as the overhead teams feel most.
Then comes the handoff. A downstream job that needs build output from an upstream job cannot read its filesystem, so the upstream job uploads an artifact and the downstream job downloads it. You wrap actions/upload-artifact and actions/download-artifact around work that lives in separate jobs only because you wanted it concurrent.
What a parallel step replaces
The proposed syntax marks individual steps to run together. Steps without the marker run in order, before and after the concurrent block:
jobs: checks: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: pnpm install - run: pnpm lint parallel: true - run: pnpm typecheck parallel: true - run: pnpm test parallel: trueOne runner. One checkout. One pnpm install. The three checks fire at the same time and read the installed dependencies off the same disk. No artifact upload between them, and no second runner to boot. The early-2026 changelog tracked the groundwork through the first half of the year, and the community thread behind the roadmap item ran for years before GitHub put it on the plan.
The billing signal
On June 1, 2026, GitHub started charging Actions minutes for each Copilot code review. Every review now draws from the same minute budget your pipelines run against. A team that splits work into extra jobs for pure concurrency pays runner-startup minutes on each one, and those minutes now compete with review minutes for the same cap.
Count your jobs, then count how many exist because you wanted parallelism rather than isolation. Those are the minutes you reclaim with parallel steps.
Which jobs to retire, which to keep
Audit your matrix now so you can move fast when the feature lands. Sort each job into one of two buckets.
Retire the jobs that share everything. Lint, type-check, and unit tests read the same checkout, need the same dependencies, and hold no secret the others should not see. They sit in separate jobs for speed alone. Collapse them into parallel steps and you drop the startup and artifact cost while keeping the concurrency.
Keep the jobs that need real isolation. A job that holds a deploy secret, runs on a different OS, or needs a clean runner the other work must not touch earns its own runner. The 2026 monorepo CI guidance draws the same line: separate jobs for separate environments, parallel steps for concurrent work inside one.
The split is the test. A job that exists for an environment stays a job. A job that exists because you wanted two commands to run at once becomes two steps.
I first shared this on LinkedIn.