LOBUS.WORKS
← All insights
Flow & Measurement

When Fixing One Bottleneck Creates Another

12 Jan 2026·7 min

The team fixed the review bottleneck. Cycle time improved. Three months later, it's rising again — this time in testing. The retrospective concludes the fix didn't hold.

This diagnosis is wrong. The fix worked completely. The constraint moved.

What a working intervention looks like

When a constrained stage is addressed — a WIP limit introduced, capacity added, a process tightened — work flows through that stage faster. That is success. But the work that previously queued there now arrives at the next stage faster too. If that downstream stage was already near its capacity, it becomes the new constraint. The symptom recurs. The location changed.

Teams read this sequence as: fix failed, problem returned. The correct reading: fix succeeded, system evolved.

Think of clearing a blocked drain. Removing one obstruction doesn't send the water flowing freely — it reveals the pressure behind it. The water surfaces at the next restriction. This is not the original problem returning. It is the original pressure finding a new exit point. The first obstruction is genuinely gone. Progress was made. The work continues.

Why migration gets mistaken for regression

Three things make constraint migration look like failure.

The symptom looks the same regardless of location. Slow delivery is slow delivery. A dashboard showing rising cycle time doesn't distinguish between "the same stage is overloaded again" and "a different stage is now the binding constraint." Without stage-level breakdown, both look identical.

Metrics that show total cycle time can't locate the constraint. They confirm it exists somewhere. They cannot tell you where it moved. Teams without per-stage visibility experience the recurrence of a symptom and have no way to confirm it's in a different place than before.

The expectation was that "fixed" meant permanent. In a system with multiple stages and variable demand, it never does. Removing one constraint increases the load on the next one. A system under sustained throughput pressure will always surface a binding constraint somewhere — the question is which stage it currently lives in.

The shape of delivery improvement

The constraint in any delivery system moves forward as each stage is addressed in turn. This is the normal shape of improvement over time.

A team starting with an obvious development bottleneck fixes it and discovers review is now constraining. They address review and find testing becomes the limit. They invest in testing and deployment starts to lag. They improve deployment frequency and now the constraint is upstream — in planning, intake, or prioritisation.

This is not a treadmill. Each time the constraint moves, the stage it left is genuinely better than it was. The system has one fewer weak link. The bottleneck is now further downstream — closer to the exit, lower cost per item that accumulates behind it. Progress has been made even though delivery still feels imperfect.

A team that has never experienced constraint migration hasn't improved far enough to see it yet. A team that sees it repeatedly is a team making consistent progress through a system that is getting healthier stage by stage.

↓ Constraint migratesSprint 1Dev⬤ CONSTRAINTReviewTestDeploySprint 4DevReview⬤ CONSTRAINTTestDeploySprint 8DevReviewTest⬤ CONSTRAINTDeploySprint 12DevReviewTestDeploy⬤ CONSTRAINTSystem is healthier overall ↑
Constraint migration over time. Each moved constraint confirms the previous intervention worked — the system has one fewer weak link each time.

Insight

An intervention that moves the constraint is a successful intervention. The system has one fewer weak link than it had before — even if a different one is now binding.

036912Throughput (items/wk)Sprint 4Dev fixedSprint 8Review fixedSprint 12Test fixedS1S3S6S9Team throughput
System throughput over time. Small dips occur as each constraint is addressed, but the overall trend is upward — each migration is a sign of progress.

How to recognise migration rather than regression

The diagnostic is the same in both cases: break cycle time by stage.

When total cycle time rises again after an improvement, the question is which stage has widened. If the previously constrained stage is healthy — items flowing through quickly, no queue depth building — and a downstream stage is now showing the widest age distribution, the constraint migrated. The intervention worked.

If the previously constrained stage has widened again, one of two things happened: the intervention addressed the symptom rather than the cause, or the root cause was addressed but not sustained. These require different responses.

The distinction matters because the response to migration is different from the response to regression. Migration means applying the intervention hierarchy to the new location — starting with WIP control, then capacity, then process redesign. Regression means diagnosing why the previous fix didn't hold and addressing the structural cause.

Both look like "cycle time is rising again." Only stage-level data tells you which one you're dealing with.

What to expect next

Constraint migration is not random. It follows the path of least improvement.

When development is addressed, review typically surfaces next — it's the stage that receives development's output and was previously buffered by slow coding. When review is addressed, testing surfaces. When testing is addressed, deployment or approval gates tend to appear. The sequence varies by team and system, but the pattern holds: whatever stage was previously masked by the upstream bottleneck becomes visible once that bottleneck is resolved.

This makes migration partially predictable. If you're about to address the development constraint, look ahead at your review stage now. Is it operating with any slack? Is reviewer capacity sufficient to absorb faster inflow? If not, the next constraint is already identifiable before the current one is fixed.

Preparing the downstream stage before the upstream intervention lands doesn't prevent migration — nothing prevents it — but it shortens the time the new constraint spends as the binding limit.

A constraint that moved is a constraint that was fixed. The system always has one — the goal is to choose which one you're working on.

The teams that make sustained delivery improvements are not the ones that found a permanent fix. There is no permanent fix, only a constraint that has moved far enough downstream that it is no longer the binding problem for the work that matters most. Constraint migration is the shape of progress. The only way to stop seeing it is to stop improving.