Language: English
Cutting PR Wait Time from 14 Minutes 12 Seconds to 3 Minutes 54 Seconds
How I cut the wait for all required checks on a pull request from 14 minutes 12 seconds to 3 minutes 54 seconds, through test selection based on changed files, splitting coverage jobs, and removing inter-job dependencies.
After opening a Pull Request, waiting for every required check to finish took 14 minutes 12 seconds. I got that down to 3 minutes 54 seconds. What I touched was job structure and dependencies — three changes in total. Individual commands were barely modified.
The Workflow Before
At the time, the Pull Request workflow looked like this.
backend-test took 5 minutes 36 seconds; frontend-test took 3 minutes 52 seconds. Those two dominated, with build and SBOM queued behind them. Build didn’t start until tests finished. storybook and format ran independently. There was no coverage-splitting matrix yet.
Responsibilities and wait time were both concentrated in the test jobs. That’s where I aimed.
Test Selection from Changed Files
Pull Requests run only the tests related to the changed sources.
変更ファイル → 関連テストを選択
Changes to a test itself run that test. Changes whose blast radius can’t be narrowed — shared packages, configuration — fall back to the full suite. When in doubt, run more. The cost of catching a missed defect later outweighs the extra execution time.
Pushes to develop and main keep full coverage. PRs are for fast feedback; integration branches are for thoroughness.
In a representative run, 14 minutes 12 seconds became 2 minutes 11 seconds. Since this compares runs with different content before and after the change, it’s not a rigorous benchmark.
There were misfires too: a documentation change under the prisma directory triggered the full suite, and I fixed the pattern afterward.
Splitting Coverage Jobs
Full coverage runs split across parallel jobs. The backend coverage job became a 4-way matrix; once all four artifacts arrive, an aggregation job merges them and checks thresholds. Aggregation finishes in 44 seconds. The regular backend-test takes 2 minutes 22 seconds.
We didn’t stop measuring coverage. Only where it’s measured and how it’s split changed.
Serial Dependencies Between DB Jobs
CI around the database ran serially.
Prisma static checks (1分37秒) → migration check (2分43秒) → endpoint E2E (2分55秒)
endpoint E2E depended not just on the E2E plan (which finishes in 19 seconds) but also had a needs on migration check. Even once the plan finished, E2E couldn’t start while waiting for migrations.
So I removed one needs. E2E starts immediately after the plan completes and proceeds on a separate track from the migration jobs.
The diff is a single dependency line, yet repeated measurements showed reductions of 165 to 168 seconds — about 38% faster. The wait time had been created by inter-job dependencies.
Overall Duration
| Target | Execution structure |
|---|---|
| Pull Request | Runs only related tests, in parallel |
| develop / main | Coverage via a 4-way matrix, then aggregated |
| DB E2E | Starts right after the plan, without waiting for migrations |
From PR creation to the last required job finishing: 3 minutes 54 seconds. Against the representative baseline run of 14 minutes 12 seconds, that’s a cut of 10 minutes 18 seconds — about 73%.
Trimming Smaller Waits
Outside of structure, I trimmed smaller waits too.
- Added concurrency cancel-in-progress so consecutive pushes to the same PR don’t keep earlier runs going; however, pushes and the weekly full scan are excluded from cancellation
- Added a paths filter to security-audit so it doesn’t fire on changes unrelated to dependencies
- Moved frontend tests that don’t touch the DOM into the Node environment
- Parallelized lightweight workflows such as markdown-link-check
The Job Graph vs. Individual Commands
In hindsight, the single most effective change was removing that one needs. One line of diff, 38% off.
Speeding up individual commands helps only within that job. Removing serialization from the job graph moves everything queued behind it forward at once. When CI feels slow, the first thing I look at is which job is waiting on what.
Based on what I presented at our achievements presentation on July 31, 2026.