Slow test suites and coding agents: how teams stop running every test on every change
When every agent runs a 30-minute suite after every small change, work stalls. The five ways large engineering teams cut test time, what each looks like in a working setup, what it misses, and where to start when your agents are waiting on tests.
A good test suite is what lets a coding agent check its own work. It’s also what grinds agent-driven development to a halt. Tell an agent to make sure everything passes, and with a 30-minute suite it will wait 30 minutes after a one-line change, then wait again after the fix. Run five agents in parallel and five full runs compete for the same machines. Cursor’s guide does the arithmetic: “If your tests take 10 minutes to run and you launch 10 agents in parallel, that’s nearly two hours of waiting” (Cursor Learn).
The problem isn’t new. Google, Meta, Mozilla, Uber and Shopify had more changes than they could test one by one long before agents, and they published what they did about it. This guide sorts those techniques into five groups, shows what each one looks like in a working setup and what it can miss, and then covers what agent vendors and teams running many agents do today.
The short answer
- Google and Meta stopped running every test on every change long ago. They run quick, targeted checks while working and before a merge, and run the full suite after the merge or on a schedule, where failures are caught and traced back to the change that caused them (Google’s system can roll that change back automatically). Google says a change that passes its fast presubmit tests has “95%+” odds of passing everything else.
- Inside the agent’s loop, run only the tests for what changed. Anthropic, Cursor and Factory all say so in their example instruction files. Put lint, formatting and type checks in hooks, and cap round trips to CI: Stripe allows at most two per agent task.
- Skip unchanged tests before you try anything clever. Build tools such as Bazel, Nx and Turborepo already skip tests whose inputs didn’t change. Real test selection saves more (Stripe runs about 5% of its tests per build) but takes dedicated infrastructure, and Meta, Google, Shopify and Mozilla all keep a full run behind theirs.
- Fix flaky tests first. Every other technique treats a red test as a real failure. With random failures, selection learns the wrong things, batches get split for nothing and agents chase ghosts.
Five ways to cut test time
Each group answers a different question. They overlap in one place: a build cache both skips tests (group 2) and shares results between machines (group 4).
| Group | The question it answers | Techniques | What it saves | What it can miss |
|---|---|---|---|---|
| 1. The agent’s loop | What should the agent run while it works? | Instructions to run targeted tests, fast checks in hooks, short test output, a cap on CI round trips | Agent time and tokens; repeated full runs | Failures in tests the agent didn’t run, caught later in CI |
| 2. Run fewer tests | Which tests can this change affect? | Skipping unchanged tests (build caches, “affected” commands), file-based selection, predictive selection | From about a quarter to over 90% of test runs, by the published figures | Dependencies the tool can’t see: libraries, config, data files, new files |
| 3. Run expensive tests later | When do the slow tests have to run? | Fast tests before merge and the full suite after, batching, merge queues, an integration branch | Waiting before each merge | Breakages that land on the main branch and are reverted later |
| 4. Run faster | How do we make one run finish sooner? | Sharding, remote execution, cutting setup time, shared caches | Sharding saves wall-clock time only; cutting setup and sharing caches also save compute | Stale results if a shared cache misses an input |
| 5. Trust the result | Does a red test mean anything? | Detecting, quarantining and fixing flaky tests | Re-runs and false alarms | A real bug hidden in a quarantined test |
What does a working setup look like?
Put together, the documented pieces form a pipeline where each stage runs more tests than the one before, and the expensive ones run least often. This is an illustration assembled from the sources below, not any one company’s setup.
| Stage | What runs | How long it should take | Documented by |
|---|---|---|---|
| The agent edits a file | Formatter, lint and type check, from a hook | Seconds | Claude Code’s hook examples; Stripe runs selected lints in under five seconds on each push |
| The agent checks its change | The tests for the files it changed | Short (our estimate; no source gives a time) | Anthropic, Cursor and Factory instruction files |
| Before the agent says it’s done | Tests of the packages that depend on the change | Minutes | Nx and Turborepo “affected” runs |
| Pull request in CI | Selected or affected tests; at most two rounds per task | Ideally under ten minutes | Meta’s ten-minute target, Stripe’s two-round cap |
| Merge | Through a merge queue if many changes land at once | Depends on the queue | GitHub, GitLab, Uber, Shopify |
| After merge | The full suite, on batches or a schedule; the change that broke it is reverted (automatically at Google, by people at LLVM and Mozilla) | Batches every 45 minutes at Google’s peak; every few hours at Meta | Google, Meta, LLVM, Mozilla |
The pattern to notice: the agent never waits for the full suite. It gets fast answers about its own change, CI checks what the change could affect, and the full suite runs on the main branch, where a failure leads to a revert rather than blocking anyone.
Stripe’s published setup is the clearest real example. Over a thousand agent-written pull requests are merged there each week, all reviewed by people (Stripe, February 2026). Each push runs selected lints locally in under five seconds. CI then runs a selection from more than three million tests. Because “CI runs cost tokens, compute, and time”, an agent gets at most two rounds of CI, and only after fixing everything it can locally; after that a person takes over. Agents work on pre-warmed machines with the Bazel and type-check caches already filled (part 2).
Spotify moved the full check out of the agent entirely. Its background agent, Honk, first ran verifiers matched to the repository (a Maven check when there’s a pom.xml), trimmed their output to the relevant errors and ran them before opening a pull request (Spotify, December 2025). By March 2026 Spotify had split “the agent runtime from the verification runtime”: a separate service runs CI, and a pull request opens only after it passes (InfoQ).
1. The agent’s loop: what should an agent run while it works?
An agent should run the tests for the code it changed, not the whole suite. That’s the advice in the example instruction files from Anthropic (“Prefer running single tests, and not the whole test suite, for performance”), Cursor (“prefer single test files for speed”) and Factory (a single file for focused changes, the full suite “before completing broad refactors”).
In practice that means four things:
- Say it in the instruction file, with the exact command for running one test file or one package. In one small study, Claude ran the full suite blind less often on the repository whose instruction file warned that “the full test suite takes >20 minutes”, and its wall-clock time fell about 24% (Khatri, 2026; exploratory, Claude only).
- Put fast, deterministic checks in hooks. A hook is a script the agent’s tool runs automatically, for example after every edit or before the agent finishes. Lint, formatting and type checks belong there: they take seconds and catch mistakes before any test runs.
- Keep test output short and saved to a file. Spotify trims verifier output to the most relevant errors; Anthropic’s parallel-agent compiler experiment printed a few lines and logged the rest. Keep the full log too: one study below found that truncated output is one reason agents rerun tests, so the agent needs to know where to read the rest.
- Cap the round trips to CI. Stripe’s two-round limit is the simplest rule to copy.
Two 2026 studies suggest agents run more tests than they need. Agents in one averaged 8.8 test runs per task, and with test execution forbidden, Claude Code on Claude Sonnet 4.5 solved 63% of 100 SWE-bench Lite tasks against 64% normally, “while saving 56% of tokens and 48% of wall-clock time” (arXiv 2606.26978). Another found agents rerunning identical tests without changing the code in about half or more of tasks, and cut cost by up to 41.73% with skills such as reading the result of a previous run instead of rerunning it (arXiv 2609.30725). Both used benchmark tasks with small, fast suites and 2024–26 models; we found no such test on Claude Opus 5.5 or GPT-6.1 Sol.
What the coding-agent vendors document, as of 17 October 2026:
| Agent | Which tests while working | What its hooks docs show |
|---|---|---|
| Claude Code (Anthropic) | Single tests, not the whole suite | After edits and before stopping; can run asynchronously |
| Cursor | Single test files | A stop hook that keeps the agent working “until all tests pass” (a full test loop, not a fast check) |
| Factory | A single file for focused changes; full suite before broad refactors | Validation after edits |
| OpenAI Codex | “Running the right test suites” | Hooks can run asynchronously; no check example |
| GitHub Copilot cloud agent | No preference stated | After tool use, for “linting, formatting, or security scans” |
| Devin | No preference stated | Devin Desktop and CLI hooks can run linters, formatters or tests after code changes |
| Amp | Its default “Ship” step runs the full suite before pushing | None found |
| Aider | Runs the test command after every edit with --auto-test |
Lint on each edited file |
“None found” means we didn’t find it in the vendor’s docs on 17 October 2026. Sources: Claude Code best practices and hooks; Cursor; Factory; Codex best practices and hooks; Copilot hooks; Devin CLI hooks and Desktop hooks; Amp; Aider.
Two details trip people up. Anthropic’s suggestion to “use a subagent to run the test suite and report only the failing tests” keeps the main agent’s context clean, but the suite still runs in full, so it saves no compute. And on GitHub, workflows on Copilot’s pull requests don’t run by default until someone clicks “Approve and run workflows” (GitHub).
2. Run fewer tests: which tests can a change affect?
There are three ways to work out which tests a change can affect, from cheapest to most involved. All of them can miss something, which is why most of the companies that publish their pipelines (Meta, Google, Shopify, Mozilla) still run everything later.
Skip tests whose inputs didn’t change. Build tools that know what each test depends on rerun a test only when the test or something it depends on changed. With Bazel this is the default: change one file, run bazel test //..., and only the tests that depend on that file run again, while the rest report their cached result (Bazel). In JavaScript monorepos, nx affected -t test runs the tests of changed projects and the projects that depend on them (Nx), and Turborepo’s --affected does the same (Turborepo). The tools name their own blind spots: Nx warns that “a missing input can produce a stale cache hit”, a shallow CI checkout makes Turborepo treat every package as changed, and Pants can’t see changes in transitive third-party dependencies (Pants).
Select tests by the files they touched. A full run records which files each test opened. When a change comes in, CI runs only the tests whose recorded files overlap with the changed files. Stripe does this across 1.2 million test units in a 50-million-line Ruby monorepo and runs about 5% of tests per build, for under 10% of the compute (Stripe). It always reruns failing tests and tests that find their files by pattern, because a new file can change behaviour without showing up in any test’s record. Shopify (2020) and Datadog’s Test Impact Analysis (Datadog) work the same way; Datadog lists what it can’t see, including library dependencies, compiler options, external services and data files.
Predict which tests are likely to fail. A model trained on past changes and test results ranks the tests for a new change by their chance of failing, and only the top slice runs. Meta’s 2019 system ran “fewer than a third” of the tests that dependency analysis would have picked, and still flagged over 99.9% of faulty changes (Meta). Mozilla (2020) and Gradle’s Develocity (docs) do the same. Develocity says it is “calibrated to catch over 99% of non-flaky test task/goal failures” and tells users to run the rest “post-merge, nightly or ready-for-release”; that’s the vendor’s own figure, and we found no independent evaluation of it.
Published results, each in the source’s own units:
| System (year) | How it selects | Saving reported | Misses reported |
|---|---|---|---|
| Meta (2019) | Model trained on change and test history | “Fewer than a third” of dependency-selected tests; testing cost halved | Under 5% of test failures, under 0.1% of faulty changes |
| Google TAP replay (2017) | Distance in the dependency graph | 42–55% of resources | None in the replayed month |
| Google presubmit replay (2014) | Recent failure history | Up to a third of test suites run | 20–30% of failing suites not selected |
| Microsoft THEO replay (2015) | Cost model | Up to 50% of test executions | 0.2–13% of defects caught later |
| Shopify (2020) | Files each test touched | About 25% of compute | 5 failing tests merged in 8,360 commits |
| Mozilla (2020) | Model trained on past regressions | 70% fewer test tasks than its previous selection | No figure given |
| Stripe (2026) | Files each test touched | About 5% of tests per build, under 10% of compute | No figure given |
“Replay” means the method was tested on past data rather than deployed. Rows use different units and aren’t directly comparable. Sources: Meta, Google 2017, Google 2014, Microsoft, Shopify, Mozilla, Stripe.
Two lessons from the table. Selection based only on which tests failed recently is weak: Google’s 2014 study missed 20–30% of failing suites that way, and its 2017 paper says such heuristics end up “mostly re-running flaky tests”. And misses are expected: Meta’s paper says any faulty change that slips through “will be detected in the stabilization stage”, its full run on the main branch.
What about letting the agent pick the tests? That’s the usual approach in agent tools, and a survey of 242 studies (December 2025, revised 2026) calls it “unsound in both directions because the selection step is a model judgment rather than a dependency analysis” (arXiv 2512.22256). One tool paper gave agents a static map from code to tests and cut regressions from 6.08% to 1.82% (TDAD, small sample, open-weight models). We found no production system where a language model decides which tests a change needs.
3. Run the expensive tests later: when do slow tests have to run?
Slow tests don’t have to block a merge. Most of the large organisations that publish their pipelines run a fast check before a change lands and the full suite afterwards, and accept that some breakages land and get reverted.
Fast before merge, everything after. Software Engineering at Google calls running every test before submission “too expensive” and limits presubmit to “only fast, reliable” tests, often a project’s unit tests (chapter 23). After submission, Google’s Test Automation Platform (TAP) runs “all potentially affected tests, including larger and slower tests”. The trade-off is explicit: “you need to catch any issues that slip by on post-submit, and accept some number of rollbacks.” Meta describes four stages: local tests; a subset on every new version of a change, ideally in “no more than ten minutes”; a “possibly more comprehensive” subset before landing; and every test on the main branch “once every few hours” (Meta). Chromium runs some tests only after submission because they’re “too slow or too expensive” (Chromium), and LLVM asks contributors to “revert to green” when post-commit tests fail (LLVM).
Not everyone agrees on the order. GitLab runs a predicted subset of tests until a merge request is approved, then the full set as the last gate before merging (GitLab). Microsoft argues that moving long tests “to a separate stage” only serves to “further defeat continuous integration”, and prefers selecting tests while still recommending a periodic full run (Microsoft Learn).
Post-merge testing only works with two things in place: a way to find which change broke the build, and cheap reverts. Google’s TAP tests batches of changes, “typically every 45 minutes during peak development time”, because testing every commit made compute grow “quadratically” (Memon et al., 2017). When a batch fails, TAP splits it into individual changes to find the culprit and can roll back a change automatically “when it has high confidence that they are the culprit” (Software Engineering at Google, chapter 23). Elsewhere it’s manual: LLVM asks whoever broke the build to revert, and Mozilla’s code sheriffs back out the offending patch.
Merge queues. A merge queue tests each change against the main branch plus the changes queued ahead of it, so two changes that pass separately can’t break main together. Some queues also batch: they test several queued changes in one CI run and split the batch to find the culprit when it fails. Only batching saves compute.
| Queue | Tests changes in batches? | When a change fails |
|---|---|---|
| GitHub merge queue | No; each pull request gets its own build | The pull request is removed and later ones rebuilt |
| GitLab merge trains | No; up to 20 pipelines run in parallel | The request is removed and later pipelines restart |
| Mergify | Yes | The batch is split until the culprit is found |
| Trunk Merge Queue | Yes | The batch is split in halves (bisected) |
| Graphite | In private beta | Each stack is tested separately, or bisected |
Sources: GitHub, GitLab, Mergify, Trunk, Graphite.
Queues have costs. Uber estimates 40–65% of its queue’s speculative builds were thrown away early, at 3.39 to 5.43 builds per change (Uber, 2025). Shopify keeps batches to eight changes because bigger ones produce “failures that are harder to isolate” (Shopify, 2019). Vendors’ savings claims, such as Trunk’s “50-70% reduction in CI minutes”, haven’t been independently measured, and in Mergify’s own 2026 report 94% of private merges through its queue went one pull request at a time (Mergify).
At agent scale the queue itself can become the bottleneck. Anthropic’s merges rose from about 2,500 a day in May 2026 to over 30,000 in September. Its engineers say they “haven’t been able to effectively replicate the industry standard of a global repository lock on the merge queue”, and rely on “post-merge and pre-deploy automated testing” instead (Anthropic; our daily coverage).
Should agent work go to a separate branch first? The research favours one shared main branch. DORA (DevOps Research and Assessment, now part of Google Cloud) links short-lived branches merged to trunk at least daily with better delivery performance, and recommends “three or fewer active branches” with no “code freezes” or “integration phases” (DORA); those are survey correlations, not experiments. The documented exception that works is Mozilla’s integration branch: patches land there with a small subset of tests, everything runs periodically, code sheriffs back out any patch that caused a failure, and the branch is merged to main “once everything looks good” (Mozilla, 2020). Cursor’s research on large agent swarms reached a similar idea: requiring “100% correctness before every single commit” caused “major serialization”, and it suggested a final “green” branch that an agent regularly fixes up before release (Cursor, February 2026). What these have in common: one shared branch, continuous merging and backouts of failing patches, not a long-lived develop branch with a stabilisation phase.
4. Run faster: how do you make one run finish sooner?
Splitting a suite across machines (sharding) makes each run finish sooner but doesn’t make it cheaper. Knapsack Pro’s example ran a seven-hour suite in about four minutes per machine on 100 machines: by our arithmetic, about 400 machine-minutes against 420 run one after another, before setup (Knapsack Pro, 2017). So sharding helps each agent get its answer sooner, but ten agents’ full runs still cost what they did.
Setup is often the bigger cost. When Shopify cut its main monolith’s 95th-percentile CI time from 45 to 18 minutes, it found that “68% of the time in CI was spent just on overhead before we actually ran any test” (Shopify, 2021). Airbnb’s move to Bazel took 4.5 years and brought “3–5x faster local build and test times”, with remote execution beating its own sharding (Airbnb).
With parallel agents, the cache decides the cost. If each agent works in its own copy of the repository with its own cache, every agent rebuilds and retests the same things. Bazel’s workspace lock stops parallel builds sharing one output folder (BuildBuddy); Nx 22.7 shares its cache across git worktrees for parallel agent work (Nx); Stripe pre-warms its agents’ machines. Linear’s test suites almost quadrupled this year while pull request wait fell from over 6 minutes to just over 5, partly because each run checks whether the same tests “have already passed for the same inputs” and skips them (Linear, September 2026).
5. Trust the result: why flaky tests come first
A flaky test passes and fails on the same code. Every technique above assumes a red test means a real failure, so flakiness breaks all of them: selection trained on history learns noise, batches get split for nothing, and agents and people learn to ignore red builds. In 2016 about 1.5% of Google’s test runs were flaky, and about 84% of observed transitions from pass to fail involved a flaky test (Google). Chromium’s commit queue tracks about 20,000 flaky tests and says that without retries almost no change would ever pass.
Fixing it pays off measurably. GitHub cut commits with a flaky red build from 1 in 11 to 1 in 200 (GitHub, 2020), and Slack’s mobile teams raised main-branch stability from 19.82% to 96% (Slack, 2022). Quarantining a flaky test has a cost Google names: it “could easily mask a real race condition”. Buildkite recommends muting over skipping, because muted tests keep running and reporting (Buildkite).
Where should you start?
These are suggestions, ordered from cheapest to most involved, each tied to the evidence above. None has been tested as a package, and we haven’t run them.
-
Tell agents what the suite costs and how to run a slice. Add a short testing section to your instruction file:
## Tests - The full suite takes about 30 minutes. Don't run it while working; CI runs it. - Run only the tests for what you changed: `pnpm test -- path/to/file.test.ts`, or one package with `pnpm turbo run test --filter <package>`. - Before finishing a change to shared code, run the tests of the packages that depend on it. - Don't rerun a test unless the code changed since the last run; read the saved log instead. - If CI fails, fix what you can locally before pushing again. After two failed CI rounds, stop and report.Each line follows a source above: the vendors’ instruction files and the Khatri study, the “affected” tools, the rerun study and Stripe’s two-round cap.
-
Put lint, formatting and type checks in hooks, and write test output to a file with only a short summary printed.
-
Turn on test-result caching or “affected” runs, and share the cache between parallel agents. Check the declared inputs first, so a missing input doesn’t give you a stale pass.
-
Measure your flaky-test rate before adding a merge queue or selection, and mute flaky tests rather than skip them.
-
Move the full suite after the merge, on a schedule or on batches, with a way to find the change that broke it and revert it. This only works if reverting is cheap and someone owns the results.
-
If you want a separate branch for agent work, copy Mozilla’s integration branch: one shared branch, a full run on a schedule, backouts of failing patches and frequent promotion to main.
-
Add a batching merge queue only when volume justifies it, and invest in real test selection last: Stripe’s and Meta’s results are the strongest, but both took dedicated infrastructure, and Meta still runs everything later.
For the agent side, see our guides to writing instructions for agents, skill libraries, hosted agent sandboxes, sandboxing agents locally, code review when agents write the code and tools that run on a Claude or ChatGPT subscription, which covers parallel-agent orchestrators.
FAQ
Should a coding agent run the whole test suite?
Not after every change. The example instruction files from Anthropic and Cursor tell agents to prefer single tests or test files, and Factory’s adds the full suite only before broad refactors. Most large organisations that publish their pipelines run the full suite after the merge or on a schedule (GitLab runs it as the last gate before merging), not while someone is working.
What is predictive test selection, and how many failures does it miss?
Predictive test selection uses a model trained on past changes and test results to run only the tests likely to fail. Meta’s 2019 system ran fewer than a third of the tests dependency analysis would have picked and missed under 0.1% of faulty changes, all caught later by a full run on the main branch. Develocity sells the same idea, with its own unaudited figures.
Does a merge queue reduce CI cost?
Only if it batches. A batching queue tests several pull requests in one run and splits the batch when it fails; GitHub’s and GitLab’s queues build each pull request separately, so they protect the main branch without saving compute. Vendor claims of 50–70% savings are unverified, and flaky tests eat into them by forcing extra splits.
How do you run many coding agents in parallel without overloading CI?
Keep cheap checks local, run selected tests in CI and limit round trips: Stripe allows at most two CI rounds per agent task, and Spotify verifies changes in a separate service before opening a pull request. A cache shared across the agents’ working copies stops them repeating each other’s builds and tests.
Is trunk-based development better than a develop branch for agent work?
DORA’s survey data links short-lived branches merged to trunk at least daily with better delivery performance, and Anthropic runs its agents on trunk with post-merge testing. An integration branch can work if it’s one shared branch, failing patches are backed out and it’s merged to main often, as Mozilla does; long-lived branches with stabilisation phases are what DORA’s data argues against.
