Karya Semi
HomeBlogSearchTagsCategoriesAboutContact
Karya Semi

Less noise. More notes.

HomeBlogAboutContactPrivacy PolicyDisclaimer

© 2026 Karya Semi. All rights reserved.

XGitHubLinkedIn
  1. Home
  2. /Categories
  3. /Software Engineering

GitHub Actions Parallel Steps: What CI Teams Should Check First

GitHub Actions parallel steps can cut CI waiting time, but only if teams clean up shared state, logs, caches, and test ownership first.

Dian Rijal Asyrof/June 29, 2026/4 min read
Illustration for GitHub Actions Parallel Steps: What CI Teams Should Check First
Advertisement

GitHub just added parallel steps for GitHub Actions, and my first reaction was boring: nice, now the messy workflow files are going to get messier.

That sounds cynical, but it comes from real CI pain. Most slow pipelines I see aren't slow because one command takes forever. They're slow because teams keep stacking unrelated work inside one job until nobody wants to touch the YAML anymore.

GitHub Actions parallel steps give teams a cleaner way to run independent checks inside the same job. That matters for small teams because it can shorten feedback time without forcing a full CI rewrite.

But there's a catch. Parallel work exposes every sloppy assumption your pipeline has been hiding.

What changed in GitHub Actions parallel steps

GitHub's changelog says Actions steps can now run in parallel. Before this, steps inside a job ran in order. If you wanted parallel work, the common path was splitting checks into separate jobs or using a matrix.

That worked, but it came with overhead. Separate jobs often repeat checkout, install dependencies again, rebuild the same app, and make logs harder to scan. Matrix jobs are great for language versions or test shards, but they feel heavy when you just want lint, typecheck, and a small test command to run at the same time.

Parallel steps sit in the middle. They let teams keep one job shape while letting independent commands run together.

For example, this kind of workflow becomes easier to reason about:

steps:
  - uses: actions/checkout@v4
  - run: npm ci
  - run: npm run lint
  - run: npm run typecheck
  - run: npm test

The dependency install still happens once. After that, lint, typecheck, and tests may be candidates for parallel execution if they don't write to the same files.

Small thing. Big difference when developers are waiting on red or green before merging.

The boring checklist before turning it on

Don't start by parallelizing everything. Start by asking one question: which commands are truly independent?

A safe first batch usually looks like this:

  • lint that reads source files
  • typecheck that writes no shared output
  • unit tests that don't depend on a running database
  • formatting checks that run in check mode

A risky batch looks different:

  • commands that write coverage files to the same path
  • tests that create shared temp files
  • scripts that mutate generated code
  • commands that start and stop the same service
  • build steps that share cache directories without locks

I've seen teams lose more time debugging flaky CI than they saved by making it faster. A 12-minute stable pipeline is annoying. A 6-minute flaky pipeline is worse because it teaches everyone to distrust the result.

That is the real trade.

Shared state is where the bugs hide

The first thing to audit is file output. Many JavaScript projects write to predictable locations: coverage/, .next/, dist/, build/, .turbo/, or a tool-specific cache folder.

If two commands write there at the same time, the failure may look random. One run passes. The next run fails because a process cleaned a directory while another process was still reading it.

I would check these before changing the workflow:

  1. Does each command write output?
  2. Can that output path be changed?
  3. Does the command need output at all in CI?
  4. Can reports be written to separate folders and merged later?

For test coverage, make each shard write its own file. For builds, don't run two builds into the same dist directory unless the tool supports it. For generated clients, generate once before the parallel section, then treat the files as read-only.

CI gets nicer when commands behave like good citizens.

Logs need more care when work runs together

Parallel steps can also make a workflow harder to debug. Sequential logs tell a story. Parallel logs can feel like five people talking in the same room.

This is where naming matters more than people admit. Give every parallel step a plain name. Avoid clever labels. A developer who is already annoyed by a failed CI run should be able to scan the page and know what broke.

Good names:

  • Lint source files
  • Run TypeScript typecheck
  • Run unit tests
  • Check formatting

Bad names:

  • Quality gate
  • Static analysis
  • Validation phase

The first set tells you where to look. The second set sounds tidy but hides the work.

If your team already uses a code review checklist for small teams, add one CI-specific item: did this change make failures easier or harder to understand?

Fast feedback is useless if nobody can read the failure.

How I would roll it out on a small team

I wouldn't make this a large migration. I'd pick one workflow and change one group of checks.

Start with the pull request workflow, because that is where wait time hurts most. Leave deploy workflows alone until the pattern has proved itself.

My rollout would look like this:

  1. Record the current median runtime for 10 recent PR runs.
  2. Pick two or three read-only checks.
  3. Run them in parallel.
  4. Watch failures for a week.
  5. Keep the change only if the logs stay clear and flakiness doesn't rise.

That's it. No grand CI program.

If a check flakes after the change, don't shrug and retry. Treat it as a useful signal. The pipeline just showed you a hidden coupling between commands.

When separate jobs are still better

Parallel steps don't replace jobs or matrices. They solve a narrower problem.

Use separate jobs when checks need different machines, permissions, services, or artifacts. Use a matrix when you need the same command across Node versions, databases, operating systems, or packages.

Use parallel steps when the commands share setup and differ only in what they check.

That distinction keeps the workflow readable. It also keeps costs under control, because repeated dependency installs can quietly become the most wasteful part of a CI system.

This pairs well with architecture decision records if the team keeps arguing about CI structure. Write down why a check is a parallel step, a separate job, or a matrix entry. Future you will forget.

The real win is shorter waiting, not clever YAML

The best version of GitHub Actions parallel steps is boring. Developers push a PR, the main checks run faster, the failure is obvious, and nobody talks about CI in standup.

That's the goal.

If the YAML becomes a puzzle, back off. If the pipeline gets flaky, back off. If nobody can tell which command failed, back off.

Parallelism is useful when it removes waiting without adding guesswork. For CI, that is the whole game.

Sources

  • GitHub Changelog: Actions steps can now be run in parallel
  • GitHub Changelog: More control over GitHub-hosted runners
Advertisement
DR

Dian Rijal Asyrof

Writes about useful AI tools, programming practice, and the craft of building reliable software.

Previous articleAI SDK 7 Upgrade Checklist for App DevelopersNext articleSmart Contract Allowances Explained: The Approval Mistake That Drains Wallets
github-actionscidevopssoftware-engineeringtesting
Advertisement
Advertisement
On this page↓
  1. What changed in GitHub Actions parallel steps
  2. The boring checklist before turning it on
  3. Shared state is where the bugs hide
  4. Logs need more care when work runs together
  5. How I would roll it out on a small team
  6. When separate jobs are still better
  7. The real win is shorter waiting, not clever YAML
  8. Sources

On this page

  1. What changed in GitHub Actions parallel steps
  2. The boring checklist before turning it on
  3. Shared state is where the bugs hide
  4. Logs need more care when work runs together
  5. How I would roll it out on a small team
  6. When separate jobs are still better
  7. The real win is shorter waiting, not clever YAML
  8. Sources

See also

Illustration for Code Review Checklist for Small Teams That Actually Prevents Bugs
Software Engineering/Jun 28, 2026

Code Review Checklist for Small Teams That Actually Prevents Bugs

A practical code review checklist for small teams, focused on risk, readability, tests, and keeping reviews fast without turning them into theatre.

3 min read
code-reviewsoftware-engineering
Illustration for Architecture Decision Records for Small Teams That Keep Repeating Debates
Software Engineering/Jun 28, 2026

Architecture Decision Records for Small Teams That Keep Repeating Debates

Architecture decision records explained for small software teams, including what to write, when to create one, and how ADRs stop old debates from coming back.

2 min read
architectureadr
Illustration for The Definitive Guide to Test-Driven Development for Modern TypeScript Projects
Software Engineering/Jun 28, 2026

The Definitive Guide to Test-Driven Development for Modern TypeScript Projects

Master Test-Driven Development (TDD) in TypeScript. Learn the Red-Green-Refactor cycle, practical patterns, and build robust, maintainable code with confidence.

5 min read
tddtypescript