Why a release candidate reaches green about once a week

An overview of the current build system, the arithmetic behind the release bottleneck, and an index of the documents in this study.

Current setup

Wave 1: build + unit Wave 2: system tests via UI Commits from many teams svc-users svc-billing ui-onboarding ui-orders … 96 more Fan-in waits for all on one revision fan-out started by hand ui-onboarding ui-orders … 96 more ui-profile: not run ui-search: flaky Test fix in the ui-search suite triggers only ui-search, then ui-profile chained on it No release candidate all 200 must pass on the same revisions
The current pipeline. Commits to the product code enter through wave 1 and reach wave 2 only when someone starts the fan-out by hand, while a commit to one module's system tests triggers only that module's UI pipeline, against the product revisions of the last fan-out. The short arrows inside wave 2 are UI pipelines that take another UI pipeline as a material. One flaky failure in ui-search keeps the other 199 green results from forming a candidate, and ui-profile, which waits on ui-search, gets no result on that revision at all. A test fix in the ui-search suite reruns ui-search and then ui-profile, and leaves the other UI pipelines and their results as they are.

Observed problems

The arithmetic of a 100-wide green gate

When a release requires every one of N independent pipelines to pass, the probability of a fully green run is (1 − p)N, where p is the chance that a single pipeline fails for reasons unrelated to the change under test. With N = 100, small per-pipeline flake rates compound into a very low chance of a green candidate.

Flake rate per UI pipeline runChance all 100 passExpected green runs per week (25 runs)
0.5%60.6%15.1
1%36.6%9.2
2%13.3%3.3
3%4.8%1.2
5%0.6%0.15

The weekly column assumes about five two-hour runs per working day, which needs someone to start the fan-out as soon as each run finishes. With a manual fan-out, the number of runs in a week is the number of times someone starts it, so the green runs per week fall below the column whenever starts are missed, even at the same flake rate. A flake rate near 3% per pipeline is enough on its own to produce the one-green-build-a-week pattern, before counting any genuine defects. A pipeline that runs 30 UI tests, each flaking once in a thousand runs, already sits at about 3%, so the per-test numbers that look acceptable to a module team become unacceptable at the level of the whole gate. A module team deciding whether a flaky test is worth fixing sees the first number, a test that fails once in a thousand runs, while the cost of that test is paid in the second.

The chains inside the second wave leave the formula unchanged, because every UI pipeline still has to pass, and they add to what each flake costs in time. A downstream UI pipeline starts only when the pipeline above it has passed, so the two-hour run is set by the longest chain of suites. When a pipeline near the top of a chain flakes, the pipelines below it wait for its rerun to pass and then run their own suites, which adds the duration of the rest of the chain to the time before the candidate can turn green.

The modular suites limit what a repair costs. When a team fixes a flaky or broken test, the commit reruns that team's UI pipeline and the pipelines chained below it, and the rest of the second wave keeps its results for the same product revisions. A repair therefore takes as long as the chain it sits in, and only the longest chain takes the full two hours. The formula still applies to every fan-out, because each fan-out runs all the UI pipelines against new product revisions, and each repair run is exposed to flakes in the pipelines it reruns.

Genuine failures make the picture worse because of batch size. Every commit made between two manual fan-outs goes into the same candidate, which is at least two hours of commits from many teams and more when the fan-out waits, and a single real defect in any of them turns the entire candidate red. The next candidate carries that defect forward until someone fixes it, along with a fresh set of commits that each carry their own risk.

The two levers that follow from this arithmetic are reducing p (determinism of tests and environments) and reducing N (how many pipelines must pass together for one candidate). The full-system release does not force N to be 200: the release can still be assembled from module versions that each passed on an earlier run. Most of the industry practices in this study pull one of those two levers, and the rest shorten the cycle so that more attempts fit into a week.

Documents in this study

Scenarios

Animated walkthroughs of the pipeline, from the happy path to a genuine defect whose fix reaches the second wave with new commits and fails again, and a promotion gate that lets the fix through alone.

After the flakes

What still keeps a candidate red once the UI suites stop flaking, from genuine defects in large batches to tests that were commented out and never restored.

Named anti-patterns

The standard industry names for what the current pipeline exhibits, where each name comes from, and how each one shows up here.

Industry practices

What other organisations running large mono repos and many services do about slow, flaky, all-or-nothing pipelines, with a mapping back to the anti-patterns.