---
title: "Run independent checks in parallel"
description: "Remove false dependencies between lint, build, test, and formatting checks so independent work can start together."
url: https://starsling.dev/ci-playbooks/techniques/parallel-independent-checks
canonicalUrl: https://starsling.dev/ci-playbooks/techniques/parallel-independent-checks
---

# Run independent checks in parallel

Remove false dependencies between lint, build, test, and formatting checks so independent work can start together.

## How it works

Identify checks that can run without another check’s output. Give those checks independent execution paths so lint, formatting, builds or tests can start together. Keep dependencies where a job consumes another job’s artifacts, and keep each required result in the final merge decision. The examples below show both splitting sequential work and removing unnecessary job dependencies.

## How to choose an approach

Compare the examples by repository setup, prerequisites, and risks before adopting one. Each company implemented this in its own environment; measure each change against your own baseline.

- **[Anthropic](https://starsling.dev/ci-playbooks/anthropic#lint-off-build-path)**: Use it when A check depends on a build job through needs: or runs inside a build-gated job, but never reads the build's output. Check before adopting: The moved check stays required, and only checks that never read the build output move.
- **[DoorDash](https://starsling.dev/ci-playbooks/doordash#lint-beside-build)**: Use it when A build command also runs linting or type checks, so the job waits for both one after the other. Check before adopting: Disable the build's own lint only once the separate lint job is a required check, so pull requests stay gated on lint.
- **[Mastra](https://starsling.dev/ci-playbooks/mastra#parallel-quality)**: Use it when Lint and formatting independently inspect the same checkout. Check before adopting: Preserve the previous file filters and both exit statuses. Concurrent writers are a different case; keep autofixes ordered and measure CPU contention.
- **[OpenAI](https://starsling.dev/ci-playbooks/openai#parallel-independent-checks)**: Use it when Independent compilation or analysis tasks share one slow sequential job. Check before adopting: Extra jobs repeat setup and use more compute. A passing aggregate must require every child to succeed.
- **[Shopify](https://starsling.dev/ci-playbooks/shopify#remove-false-dependency)**: Use it when Long jobs wait on another job whose outputs and artifacts they do not use. Check before adopting: Keep dependencies that are deliberate gates, such as checks that must pass before a deploy.
- **[Uber](https://starsling.dev/ci-playbooks/uber#parallel-independent-checks)**: Use it when A long job runs heavy steps one after another, and at least two of them read none of each other's outputs. Check before adopting: Separate jobs repeat checkout and setup. Measure the longest path, and keep the required aggregate waiting on every split check. Adapted for GitHub Actions; compare the original system with yours.

## Apply this technique

````text
Evaluate and apply this CI technique to my repository: Run independent checks in parallel.

Remove false dependencies between lint, build, test, and formatting checks so independent work can start together.

Read the technique and its source-backed company examples: https://starsling.dev/ci-playbooks/techniques/parallel-independent-checks.md

Inspect this repository’s CI workflows, build and test commands, dependencies, and recent run timings. Identify where this technique applies and explain the expected benefit using this repository’s evidence.
Measure a baseline from recent comparable runs: elapsed time, queue time, runner minutes and failures where available. If data is unavailable, say what cannot be measured.
Compare relevant company approaches, checking prerequisites, platform differences and tradeoffs. Rank applicable options by evidence, fit and measurable opportunity; do not present company results as predictions for this repo.
Recommend the smallest safe change, show what checks and fallback paths remain, and ASK ME WHICH CHANGE TO APPROVE BEFORE EDITING ANY FILES.
Only after approval, work on a new feature branch, make one reversible change, and open a reviewable pull request. Never merge or push to a default or protected branch.
Keep required checks, test coverage, deployment and release behavior intact. Validate the change and compare equivalent runs where possible; report limitations and what should be monitored after merge.
````

## How companies used this technique

Read what each company changed and follow the original sources.

### Anthropic: Run build-free checks without waiting for the build

Bun's source-lint tests read only the source tree, yet each test shard ran them after waiting for the full build. They now run in their own GitHub Actions workflow, and the test shards exclude them.

Evidence: Source PR/commit evidence

Use it when: A check depends on a build job through needs: or runs inside a build-gated job, but never reads the build's output.

Before applying it: The moved check stays required, and only checks that never read the build output move.

[Read more in the Anthropic playbook](https://starsling.dev/ci-playbooks/anthropic#lint-off-build-path)

[Primary source](https://github.com/oven-sh/bun/pull/34682)

### DoorDash: Run lint beside the build, as its own step

Next.js can lint as part of its build, but that lint runs late in the build. DoorDash decoupled ESLint from the Next.js build and runs its three minutes of linting in parallel with the build, so developers see lint results five minutes sooner. Together with the cobuild fix and the cache change, this cut CI runtime by six minutes and halved billed agent minutes.

Evidence: Company-reported result or observation

Implementing these three changes decreased CI runtime by six minutes and cut billed minutes for agent usage in half. ([Source](https://careersatdoordash.com/blog/how-doordash-slashed-web-developer-build-times/))

Use it when: A build command also runs linting or type checks, so the job waits for both one after the other.

Before applying it: Disable the build's own lint only once the separate lint job is a required check, so pull requests stay gated on lint.

[Read more in the DoorDash playbook](https://starsling.dev/ci-playbooks/doordash#lint-beside-build)

[Primary source](https://careersatdoordash.com/blog/how-doordash-slashed-web-developer-build-times/)

### Mastra: Run independent lint and formatting checks together

Mastra scheduled ESLint and formatting checks in one Turbo invocation, applying the parallel-steps recipe through the task runner. The write/autofix commands stayed sequential, and formatting tasks remained uncached.

Evidence: Source PR/commit evidence

Use it when: Lint and formatting independently inspect the same checkout.

Before applying it: Preserve the previous file filters and both exit statuses. Concurrent writers are a different case; keep autofixes ordered and measure CPU contention.

[Read more in the Mastra playbook](https://starsling.dev/ci-playbooks/mastra#parallel-quality)

[Primary source](https://github.com/mastra-ai/mastra/pull/18428)

### OpenAI: Run independent checks alongside each other

The CLI moved Windows test compilation out of the Linux test script into its own job. The Go SDK split lint into four matrix groups behind a required aggregate.

Evidence: Source PR/commit evidence

Windows compilation runs alongside the Linux tests ([Source](https://github.com/openai/openai-cli/pull/489))

Use it when: Independent compilation or analysis tasks share one slow sequential job.

Before applying it: Extra jobs repeat setup and use more compute. A passing aggregate must require every child to succeed.

[Read more in the OpenAI playbook](https://starsling.dev/ci-playbooks/openai#parallel-independent-checks)

[Primary source](https://github.com/openai/openai-cli/pull/489)

### Shopify: Let tests start without waiting for lint

Tecnix's test legs waited for its basic checks before starting. Shopify/tecnix#74 removes that edge; lint problems still turn the required aggregate basic-checks job red while the much longer test legs run alongside it.

Evidence: Source PR/commit evidence

Merged 2026-10-01; the test job on the default branch has no needs edge. ([Source](https://github.com/Shopify/tecnix/pull/74))

Use it when: Long jobs wait on another job whose outputs and artifacts they do not use.

Before applying it: Keep dependencies that are deliberate gates, such as checks that must pass before a deploy.

[Read more in the Shopify playbook](https://starsling.dev/ci-playbooks/shopify#remove-false-dependency)

[Primary source](https://github.com/Shopify/tecnix/pull/74)

### Uber: Run independent checks at the same time

**Translated to GitHub Actions**

- What Uber built: Uber's landing validation ran environment preparation, pre-checks, changed-targets calculation, build and test, and publishing in sequence.
- Your GitHub Actions version: Run a check that depends on neither the build nor the change calculation in parallel with them.

Uber's landing validation ran environment preparation, pre-checks, CTC, Bazel build and test, and result publishing in sequence. Its P95 and P99 breakdown showed Bazel build and test, CTC and the resolve-dependencies check as the main consumers. The dependency check depends on neither CTC nor the build, so Uber moved it to run in parallel.

Evidence: Documented technique

Use it when: A long job runs heavy steps one after another, and at least two of them read none of each other's outputs.

Before applying it: Separate jobs repeat checkout and setup. Measure the longest path, and keep the required aggregate waiting on every split check.

GitHub Actions adaptation: Compare the source system with your own workflow before applying this translation.

[Read more in the Uber playbook](https://starsling.dev/ci-playbooks/uber#parallel-independent-checks)

[Primary source](https://www.uber.com/us/en/blog/how-we-halved-go-monorepo-ci-build-time/)

## CI optimization is continuous work.

Apply this technique yourself, or use StarSling Runners for faster GitHub Actions and optional agent-driven optimization PRs, which teams on eligible paid plans can turn on.

[Get self-improving CI](https://starsling.dev/products/runners)

## Related techniques

### [Clean up independent test resources concurrently](https://starsling.dev/ci-playbooks/techniques/parallel-cleanup)

Independent index deletions do not need a separate serial wait per index.

1 implementation · 1 company (Mastra)

### [Compress release artifacts in parallel](https://starsling.dev/ci-playbooks/techniques/parallel-packaging)

Compress independent release binaries two at a time.

1 implementation · 1 company (OpenAI)

### [Let shared packages without a build step stay cacheable](https://starsling.dev/ci-playbooks/techniques/uncluster-no-op-projects)

Treat a package with nothing to build as cacheable, so its dependents spread across every CI agent.

1 implementation · 1 company (DoorDash)

## Company Playbooks

### [Anthropic](https://starsling.dev/ci-playbooks/anthropic)

Run only affected tests

### [DoorDash](https://starsling.dev/ci-playbooks/doordash)

Run build and test in parallel, sharded across CI agents

### [Linear](https://starsling.dev/ci-playbooks/linear)

Benchmark the same job on faster hardware

### [Mastra](https://starsling.dev/ci-playbooks/mastra)

StarSling runners for the slowest test workflow

### [OpenAI](https://starsling.dev/ci-playbooks/openai)

Rank CI fixes by the minutes they save

### [Ramp](https://starsling.dev/ci-playbooks/ramp)

Move a CPU-bound test suite to a faster CPU

### [Shopify](https://starsling.dev/ci-playbooks/shopify)

Let an agent iterate against one CI metric

### [Spotify](https://starsling.dev/ci-playbooks/spotify)

Build arm64 on native arm64 runners

### [Stripe](https://starsling.dev/ci-playbooks/stripe)

Run only the tests a change can reach

### [Uber](https://starsling.dev/ci-playbooks/uber)

Build the merge-queue speculations most likely to be needed

## Related guides

Implementation guides for this technique.

### [Shard tests across parallel jobs](https://starsling.dev/best-practices/github-actions/shard-tests)

Use native test sharding and a job matrix to divide a long suite.

### [Parallelize independent jobs](https://starsling.dev/github-actions/optimizations/parallelize-independent-jobs)

Run independent validation lanes concurrently and keep genuine job dependencies.
