The new bottleneck is proof.
Linear reports that its test suites almost quadrupled during 2026. Over the same period, the company reduced pull request wait time from more than six minutes to just over five. It also cut runner time per test roughly in half.[1]
Those are Linear's measurements on Linear's codebase and CI setup. They are not a forecast for another repository. The method transfers better than the percentages. Measure how long a pull request waits and how much machine time the run consumes. A change can improve one gauge while hurting the other.
Small gates can hold every car.
Linear found change-detection jobs sitting in front of all test shards. A full checkout made those small jobs expensive. The team capped history, removed checkout where no working tree was needed, and used sparse, blobless checkout where a path diff was required. The reported median for one change-detection job fell from 26 seconds to 8 seconds.[1]
GitHub's checkout action fetches one commit by default. It also supports sparse checkout and a partial-clone filter.[2] Do not cargo-cult a shallow clone. First write down the exact question the gate must answer. A path diff needs enough history to identify the comparison base. A metadata-only decision may not need a working tree at all.
A ten-second gate in front of eight shards costs ten seconds of wall time. It can also leave eight machines waiting for permission to work.
Setup belongs on the timing board.
Linear also reports that seven short checks each paid for a runner, checkout, and dependency install. The team grouped them into two jobs and ran the checks concurrently inside those jobs. Based on its June usage, Linear says this saved about 87,000 runner-minutes per month.[1]
The same article describes filtered package installation. One API workflow moved from a full workspace install that took 44 to 73 seconds to a filtered install that took 16 to 18 seconds. pnpm documents selectors for a package, its dependencies, its dependents, directory globs, and packages changed since a commit.[3]
Filtering is policy, not a free speed switch. If the selector misses a dependent package, the run gets faster by skipping evidence. Put the selector under tests. Keep a scheduled full-workspace lane as a backstop when the change graph is hard to prove.
Delete the tail that gates nothing.
Linear found a cache-marker write on the merge path after tests had passed. Moving that write to a job that gated nothing removed 42 seconds from the path for affected API pull requests and merge-queue entries.[1]
This is the cleanest tuning question in the shop. If a post-test step fails, should the pull request remain blocked? If the answer is no, move it out of the required path. Keep its failure visible. Do not make the merge wait for bookkeeping.
Run the audit in this order.
- Draw the dependency graph and mark the longest required path.
- Measure queue time, gate time, setup, useful work, and tail separately.
- Remove checkout, package installation, and service boot where the job does not use them.
- Batch short checks only when failure output stays clear and reruns stay cheap.
- Move non-gating writes, uploads, and reports after the merge gate.
- Track wall time and runner-minutes after every change.