The 38-Minute Pipeline That Nobody Trusts
An e-commerce company runs a monorepo with 42 services on a shared CI system. The main branch pipeline takes 38 minutes: 12 minutes building all services, 18 minutes running integration tests against a shared staging namespace, and 8 minutes for security scans. In the last 30 days, 14% of pipeline runs failed, and 61% of those failures were tests that passed on rerun. Developers routinely rerun failed jobs, and release managers have started approving deployments despite red integration stages because the staging namespace is often occupied by another team's test data. The team proposes two changes: shard tests across 8 runners and move integration tests to a per-pull-request ephemeral namespace. The platform budget allows 20% more compute but no additional CI vendor spend. The release cadence is 30 production deployments per week, and the change failure rate has risen from 8% to 15%.
1. What is the most likely root cause of the rising change failure rate, and how would you distinguish flaky tests from genuine integration defects using data the pipeline already has?
Read the worked answer
The most likely root cause is that the pipeline's red/green signal has lost credibility, not simply that tests are flaky. A test that passes on rerun is only a candidate flake; the pass may come from different data, a different runner, a different test order, or a staging namespace that another team has since vacated. The shared staging namespace is especially important because it makes tests non-hermetic: one team's fixtures can collide with another's, and failures can depend on execution order or concurrent load.
Use the pipeline's history to separate the two:
- Per-test rerun-pass rate over time. A genuine defect usually fails consistently for the same commit and service. A flake tends to pass on rerun without a code change, or fails in unrelated services and in different orderings.
- Failure clustering. If failures concentrate on runner IDs, times of day, parallel shards, or the presence of another team's data, suspect isolation and resource contention.
- Changed-code correlation. Map failures to changed services and recent commits. Genuine integration defects should correlate with the change; flakes should not.
- Failure signature. Compare stack traces, response bodies, and timing. Data collisions and timeout signatures point to flakiness; deterministic assertion failures point to defects.
Do not quarantine a test merely because it passed on rerun. Require an owner, a linked failure record, and an expiry date. The rising change failure rate also suggests that red stages are being overridden; track override frequency and attribute escaped defects to it.
2. Evaluate the two proposed changes. Which would you implement first, and what guardrails and metrics would prove the change worked?
Read the worked answer
I would implement per-pull-request ephemeral namespaces first, because the shared staging namespace is corrupting the meaning of the test result. Sharding tests across 8 runners may reduce wall-clock time, but if tests share state or depend on ordering, sharding can increase flakiness and make failures harder to reproduce. It also does not solve data collisions. Ephemeral namespaces make each run isolated and reproducible, which is the prerequisite for trusting a red stage.
Sharding is still useful, but after isolation. Start with the tests affected by changed services, use seeded fixtures and unique namespace names, and set a TTL so abandoned namespaces do not consume the 20% compute headroom. Add a quarantine policy: a test can be quarantined only with an owner, a ticket, and a maximum age; the pipeline must still run it in a non-blocking lane and report it.
Guardrails should include a blocking integration gate, no admin bypass without an incident record, and a canary deployment step so a bad change is caught before full rollout. Measure pipeline p50/p95 duration, flake rate, rerun rate, change failure rate, escaped defects, deployment frequency, and quarantine age. A successful result is lower rerun rate and lower change failure rate without simply making the gate easier to pass.
3. How should release managers treat red integration stages while remediation is underway?
Read the worked answer
They should stop treating a red integration stage as advisory. If the stage is known to be unreliable, the correct response is to fix or quarantine the specific unreliable tests, not to approve the whole pipeline despite red. A blanket override removes the only automated evidence that the release is safe and trains the organization to ignore failures.
Define two categories explicitly: blocking and advisory. Blocking failures must be resolved or tied to a time-bound exception approved by engineering and release management. Advisory checks can run without blocking, but they must not be described as security or integration gates. If a known flake triggers a block, quarantine that test at the test level, rerun only that test, and attach the failure record to the release. Do not rerun the entire pipeline until it goes green.
Until the gate is trusted, require a canary or progressive rollout with automated rollback and an explicit rollback owner. Release managers should also review override counts weekly and escalate any service that repeatedly bypasses the gate.