Where Test Parallelization Stops — Why We Capped at 7 Workers, Not 16
"Tests are slow, parallelize them" isn't always the right answer. Six months of data on diminishing returns.
A year ago our test runs took 17 minutes. Too long. Believing parallelization was the answer, we scaled workers 4 → 8 → 16.
4 workers: 17 min
8 workers: 11 min
16 workers: 10 minAt 16 workers we shaved one minute from 11 to 10. Cost was 4× the 4-worker run. Six months of measurement told us where diminishing returns started.
The four bottlenecks
Tests don't speed up linearly with workers because of one of four bottlenecks.
Bottleneck 1 — shared resource (DB, cache)
If tests share one DB instance, more parallelism makes the DB the serialization point. Our case: a single Postgres. Fine to 8 workers; at 16 the connection pool saturated.
Diagnose: as parallelism increases, measure DB latency. The point where average latency starts climbing is where the bottleneck begins.
Bottleneck 2 — slow setup — fixed cost
Each worker spends fixed time on boot + dependency install + DB migration. If setup is 3 minutes, parallelism doesn't reduce it.
Our case — 3 of the 17 minutes were setup. At 16 workers, still 3 minutes setup. Test execution shrank 14 → 7 min but total 17 → 10 min. Setup defines the floor.
Fix: pre-warmed worker pool, dependency caching, reusable DB snapshots. Cutting setup from 3 min to 30 sec yields the largest improvement.
Bottleneck 3 — uneven distribution — the long pole
Workers don't get equal work. One worker that picks up an unusually slow test group makes all the others wait.
Our data — 15 of 16 workers finished in 4 min, one finished in 9 min. Total time: 9 min. The other 15 spent the difference waiting.
Fix: distribute by historical execution time (not by simple chunking). Or work-stealing — workers that finish early pick up unfinished jobs from others.
Bottleneck 4 — shared external dependency
If tests call external APIs (Stripe sandbox, etc.), the API's rate limit becomes the ceiling.
Our case — payment tests hit Stripe sandbox's 50/min limit. Fine to 8 workers; at 16, rate-limit retries turned the parallelism into a negative.
Fix: replace external API calls with mocks, or request a high-rate vendor sandbox.
Our ceiling — converging at 7 workers
After analyzing the four bottlenecks, we re-measured:
Workers | Total time | Bottleneck
────────┼────────────┼───────────────────────
1 | 38 min | (none)
2 | 22 min | (none)
4 | 14 min | DB pool starting
7 | 9 min | setup + DB threshold
8 | 8 min | DB pool saturating
16 | 7.5 min | setup dominant
32 | 7.5 min | setup only — parallelism *meaningless*7–8 workers is the peak efficiency point. Past that, cost rises while time barely moves. Knowing this up front halves CI cost.
To go faster — not workers, setup
Past 7–8 workers, our next move wasn't more workers. It was cutting setup. Four changes:
- Reusable DB snapshots — workers don't re-migrate; they mount a pre-built snapshot.
- Dependency cache — all workers share the same cache.
- Worker warm pool — keep 5 workers always running.
- Pre-loaded fixtures — load test data before the first test.
These four took total time 9 min → 4 min. Same 7 workers, 2× saving. Setup is a much bigger lever than worker count.
If you're trying to shorten CI test time by adding workers, first measure which of the four bottlenecks (DB pool, setup, uneven distribution, external rate limits) is active. Scale without measuring and 16 workers gives roughly the same time as 7 at 4× cost.
Related posts
When a Product Manager Ships Code, Who Owns the Outage?
In organizations where product managers write code with AI and several agents work at once, who checks what before a change reaches production? A role design for verification, approval, and recovery that is independent of the author, grounded in NIST SSDF, SLSA provenance, and the Google SRE postmortem culture.
John Baek
An Eclipse Plugin for the Agent Era — Task Context Was Already the Problem 20 Years Ago
The problem Mylyn set out to solve in the mid-2000s is the agent context problem. What changed is that the thing reading that context is no longer only a person.
Yeongsang Kim
A VS Code Extension for the Agent Era — What Developers Look At Now
Once writing code got cheap, a developer's time moved to judging and approving. Here is why those jobs cannot live outside the editor, and the choices behind the CollabOps VS Code extension.
Seungbaek Lee