June 22, 2026
How to Measure Flaky Test Risk in CI Before It Slows Release Velocity
Learn how to measure flaky test risk in CI using failure reproducibility, retry rate, CI noise, and suite-level signals that protect release velocity.
Flaky tests are easy to notice and hard to quantify. A red build that goes green on rerun feels annoying, but the real cost is usually hidden, extra triage time, delayed merges, lower trust in test signals, and teams starting to ignore CI altogether. That is why the useful question is not “Do we have flaky tests?”, but “How much flaky test risk in CI is affecting release velocity right now?”
The measurement challenge matters because flakiness is not one problem. A test that fails once every 200 runs has a different operational impact than a test that fails in bursts on a single agent class, or a suite where reruns mask real regressions. If you want to keep CI useful, you need metrics that separate signal from noise, show where instability accumulates, and help you decide whether to quarantine, rewrite, or leave a test alone.
A flaky suite does not just waste compute, it changes team behavior. The moment engineers stop believing the pipeline, release velocity starts to depend on human override rather than automated confidence.
What flaky test risk actually means
Flaky test risk in CI is the probability that test instability will distort a release decision, not just the probability that a test fails. That distinction is important. A test can be flaky and still have low business impact if it runs rarely, is isolated, and is easy to interpret. Another test can be only mildly unstable and still create major drag if it blocks a critical path, runs on every pull request, or is frequently retried.
In practice, risk is a function of four things:
- Frequency of failure across repeated runs.
- Reproducibility of the failure under controlled conditions.
- Blast radius of the test, meaning how many builds or teams it affects.
- Operational response, especially reruns, quarantines, and manual approvals.
The last point is often ignored. A test that fails 5 percent of the time might sound acceptable until you see that every failure triggers two reruns and 15 minutes of human attention. That is how CI noise turns into a release bottleneck.
For background, continuous integration is the practice of integrating code frequently and validating it with automated checks, while test automation is the use of software to execute tests without manual intervention (continuous integration, test automation). Flakiness erodes both by making automation untrustworthy.
The core metrics that expose flaky test risk in CI
If you only track pass rate, you will miss most of the risk. You need a small set of metrics that describe failure behavior, rerun behavior, and stability over time.
1. Failure rate by test and by suite
Start with the simplest signal, the number of failed executions divided by total executions. Compute it at two levels:
- Per test case, to find the worst offenders.
- Per suite or job, to see where instability clusters.
This is useful, but not sufficient. A test with a 2 percent failure rate and 1,000 runs a day creates more noise than a test with a 20 percent failure rate and 10 runs a day if the former sits on a critical PR gate.
2. Retry rate
Retry rate is the proportion of failures that are retried automatically or manually. It is one of the best proxy metrics for perceived flakiness because teams usually retry when they think a failure is non-deterministic.
Track:
- Failed tests that were rerun.
- Failed builds that required a rerun.
- Reruns needed before a green result.
A rising retry rate often means the suite is losing trust even if the headline pass rate stays stable.
3. Failure reproducibility
Failure reproducibility is the share of failures you can reproduce deterministically under similar conditions. This can be measured through:
- Local reruns with the same commit.
- Repeated runs in a controlled environment.
- Failure reproduction on the same agent type or browser version.
If a failure cannot be reproduced consistently, it is a candidate for flakiness analysis. If it can be reproduced every time, it may be a real product defect, a test bug, or an environment issue, but not necessarily a flaky test.
4. CI noise ratio
CI noise is the volume of low-confidence failures relative to meaningful failures. A practical way to estimate it is:
- Count failures that disappear on rerun, or
- Count failures that lack a correlated code change, environment change, or dependency change.
Noise ratio is especially useful for release managers because it frames the question in terms of decision quality. High CI noise means the pipeline is producing too many false alarms.
5. Mean time to confidence
This is the time from first failed run to the moment the team trusts the result enough to proceed. If a build fails, reruns twice, and needs a human to inspect logs before merge approval, your issue is not just flakiness, it is delayed confidence.
This metric is often more actionable than raw failure rate because it captures the delay introduced by ambiguity.
A practical risk model you can compute today
You do not need a sophisticated ML system to estimate flaky test risk in CI. A weighted score is usually enough to prioritize effort.
A simple model looks like this:
Flaky Test Risk Score = Failure Frequency × Impact Weight × Uncertainty Weight × Operational Cost
Where:
- Failure Frequency is the failure rate for a test or suite.
- Impact Weight reflects where the test sits in the pipeline, for example PR gate, nightly, or pre-release only.
- Uncertainty Weight is higher when failures are hard to reproduce.
- Operational Cost accounts for reruns, triage time, and blocked merges.
You do not need precise numbers to start. Even ordinal scoring, such as 1 to 5, can help teams rank tests by risk. The key is consistency.
Example scoring rubric
| Signal | Low | Medium | High |
|---|---|---|---|
| Failure frequency | Rare | Occasional | Frequent |
| Reproducibility | Deterministic | Sometimes reproducible | Hard to reproduce |
| Pipeline impact | Nightly only | Non-blocking PR check | Blocking gate |
| Operational cost | Low | Moderate | High |
If a test is frequently flaky, hard to reproduce, and blocks merges, it should move to the top of your remediation queue even if the underlying failure rate looks small.
Why reruns can hide release risk instead of reducing it
Automatic retry is often treated as a harmless mitigation. In reality, retries can mask both signal and risk.
Retries are useful when they absorb infrastructure noise, such as transient network failures or short-lived browser startup issues. But when retries become the default answer to every red build, they create several problems:
- They reduce pressure to fix the root cause.
- They inflate apparent stability.
- They increase cycle time.
- They make the team tolerate poor test hygiene.
A retry policy should be a diagnostic tool, not a substitute for reliability engineering.
You can measure this effect by comparing first-attempt failure rate to final pass rate after retries. The gap between those two numbers is a useful measure of hidden CI drag. If 98 percent of builds eventually pass but 12 percent need at least one retry, the final pass rate is misleading. The team still pays for the failed first attempt.
A better practice is to report three values together:
- First-pass success rate.
- Final success rate after retries.
- Retry-induced delay per build.
This makes it obvious when confidence is being purchased with time.
How to separate flaky tests from genuine product failures
Not every unstable test is a flaky test. Misclassification wastes engineering time, so the measurement process needs a basic triage path.
Look for these flaky signatures
- Failures that disappear on rerun without code changes.
- Failures concentrated on one runner, browser, or agent type.
- Timing-sensitive assertions, such as fixed sleeps or loose synchronization.
- Tests that fail only under parallel execution.
- Failures that correlate with unrelated infrastructure events.
Look for these non-flaky signatures
- Failures that reproduce consistently on the same commit.
- Failures that align with a specific code path or input.
- Failures that remain after environment normalization.
- Failures that show a clear defect pattern in logs or traces.
This distinction matters because the remediation differs. Flaky tests need stabilization, better waits, isolation, or environment control. Real defects need product fixes. Infrastructure issues may require CI topology changes, resource scaling, or container cleanup.
Data to collect from CI if you want credible metrics
You cannot measure flaky test risk in CI with only a green or red build status. Capture enough context to explain why a run failed and whether the failure was likely flaky.
Minimum useful data fields
- Commit SHA
- Branch name or PR number
- Test name or identifier
- Suite name
- Start and end timestamps
- Runner or agent label
- Browser or runtime version
- Retry count
- Failure reason or error signature
- Environment metadata, such as container image, shard, or node type
- Link to logs, screenshots, traces, or videos where available
This data lets you ask better questions, such as whether a failure is tied to one shard, one browser version, or one time window.
If you do not store this metadata centrally, you will spend too much time trying to infer patterns from scattered logs.
A simple dashboard that release teams can actually use
The best flakiness dashboard is one that answers a few operational questions quickly. It does not need to be fancy. It needs to support decisions.
Track these views:
- Top flaky tests by rerun count
- Top flaky tests by blocked merges
- Suite-level first-pass success rate
- Failure reproducibility by environment
- Trend of CI noise over time
- Median time to green after first failure
A useful dashboard also distinguishes between:
- Test-level flakiness,
- Environment-level instability,
- Product defects,
- And pipeline configuration issues.
When these are mixed together, teams fix the wrong thing.
How to estimate the business impact of flaky test risk
Engineering teams often underestimate the cost because each flaky event looks small. The cost becomes visible when you aggregate it across a release train.
A practical way to estimate impact is:
Impact = affected builds × average reruns per build × average triage time + blocked release delay
You do not need perfect accounting. Even rough estimates reveal where flakiness is expensive.
For example, if a PR gate reruns often enough to add ten minutes to a quarter of developer merges, that is a release velocity problem, not just a QA annoyance. If a nightly suite regularly produces ambiguous failures that require morning triage, then release confidence is being deferred into the next workday.
Two common hidden costs are worth calling out:
- Developer context switching, because engineers stop what they are doing to inspect uncertain failures.
- Decision latency, because release managers wait for a “good enough” signal instead of a clean one.
The result is slower throughput, even if the number of finished tests goes up.
Implementation patterns that reduce risk without overcorrecting
The best response to flakiness is not always to delete tests. Sometimes a targeted fix is enough.
Improve synchronization before adding more retries
Many UI flake patterns come from weak waits, fixed sleeps, or assertions that fire before the application state is stable. Prefer condition-based waiting over time-based waiting.
typescript
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByText('Saved')).toBeVisible({ timeout: 5000 });
A deterministic wait reduces both failure frequency and retry dependence.
Add test isolation
Shared state is a common source of hidden risk. If tests depend on the same user account, database row, or email inbox, failures can look random even when the cause is predictable.
Good isolation practices include:
- Unique test data per run.
- Resetting external state between tests.
- Avoiding shared mutable fixtures.
- Sharding with awareness of resource contention.
Distinguish infra instability from test instability
If failures cluster by node, browser image, or region, the problem may not be the test. Add environment labels to your failure analysis so you can spot patterns before rewriting a healthy test.
A minimal GitHub Actions example can help surface this metadata:
name: ci
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test
- name: print runner metadata
run: echo "runner=$"
This is not a flakiness solution by itself, but it helps you connect failures to execution context.
When to quarantine, when to fix, and when to delete
A measurement-first approach should end in action. The main choices are quarantine, fix, or delete.
Quarantine when
- The test is valuable but actively blocking merges.
- The failure is noisy, hard to stabilize immediately, and low enough risk to temporarily remove from the critical path.
- You have an owner and a deadline for remediation.
Quarantine is not a permanent solution. If it becomes permanent, the suite has simply been re-labeled, not improved.
Fix when
- The test covers a critical user path.
- The failure pattern is well understood.
- The test is expensive to rerun or causes significant release drag.
Fixing may include improving waits, cleaning data setup, or making the test less coupled to implementation details.
Delete when
- The test duplicates other coverage.
- The assertion is too brittle to provide meaningful value.
- The business value no longer justifies the maintenance cost.
Deleting a low-value flaky test often improves release velocity more than months of triage.
Common mistakes in flaky test measurement
Treating all failures as equal
A minor visual assertion failure is not the same as a failed payment flow. Weight your risk model by criticality.
Ignoring rerun cost
If the team only tracks eventual success, they miss the real drag created by retries.
Measuring at the wrong level
Suite-level pass rate can hide one unstable test that dominates all the noise. Individual test-level metrics are essential.
Forgetting environment drift
Changes in browser versions, container images, infrastructure limits, or parallelism can create flake patterns that look like code regressions.
Turning every flaky test into a policy debate
Some tests need engineering work, some need observability, and some need to be removed. Avoid treating all flakiness as a reason to change retry policy.
A practical operating model for teams
If you want this to stick, make it part of routine CI review, not a one-time cleanup project.
A workable cadence looks like this:
- Daily, review top rerun-heavy failures.
- Weekly, inspect trendlines for CI noise and first-pass success rate.
- Per release, check whether flaky test risk is affecting merge latency or sign-off confidence.
- Monthly, decide which tests to stabilize, quarantine, or delete.
Assign ownership. Release engineers and SDETs often have the best view of pipeline behavior, but application teams need to own the tests themselves.
If no one owns a flaky test, the real owner becomes the release manager who has to explain why automation cannot be trusted.
What good looks like
A healthy CI system is not one with zero flakiness. That is unrealistic in most large engineering organizations. A healthy system is one where:
- Flaky tests are visible, not hidden behind retries.
- Reproducibility is tracked, not guessed.
- CI noise is measured separately from genuine failures.
- Release velocity is protected by fast triage and clear ownership.
- The team trusts the pipeline enough to act on its results.
The goal is not perfection, it is predictable decision quality.
Final takeaway
If you want to control flaky test risk in CI before it slows release velocity, focus on the metrics that expose hidden drag: first-pass failure rate, retry rate, reproducibility, CI noise, and time to confidence. Those signals tell you which tests are merely annoying and which ones are distorting release decisions.
Once you can measure the risk, the remediation path becomes much clearer. Some tests need better synchronization, some need isolation, some need quarantine, and some need to be removed. The teams that keep release velocity high are usually not the ones with the fewest failures, they are the ones that understand which failures can be trusted.