High Five Studio

September 2026

Progress Rings at 60% Cut Rebuilds 31% While Debugging

Why a progress ring at sixty percent makes developers rebuild instead of debug, and how partial signals shape our estimates of unfinished work

Progress Rings at 60% Cut Rebuilds 31% While Debugging

There is a specific moment in front-end work when a progress ring sits at sixty percent, the spinner keeps turning, and the developer watching it has to decide whether to keep debugging the thing that is slow or rebuild the thing that is broken. That decision is not really about JavaScript. It is about how humans estimate unfinished work, how we read partial signals as either encouragement or warning, and why two competent engineers looking at the same ring can walk away with opposite conclusions.

The number sixty is doing more work than it deserves. A progress ring at sixty percent is not a measurement of anything. It is a rendering of a promise — that someone, somewhere, defined a total, and that the current state is roughly three-fifths of the way through it. When that promise turns out to be wrong, the ring becomes a liability: it anchors the team to a completion story that no longer matches reality. This is where rebuilds get triggered, and it is why rebuilds so often overshoot. A team that rebuilds at sixty percent usually discovers, somewhere around the new forty percent, that the old sixty was not measuring the same thing at all.

The ring is a claim, not a fact

Progress indicators inherit their authority from a convention that most users never question: that the bar or ring corresponds to a known denominator. In file transfers and installers, that is roughly true. In application code, it almost never is. A progress ring in a build tool, a data migration, a refactor dashboard, or a long-running client-side task is usually computed from a heuristic — files processed, tasks queued, steps enumerated — and each of those heuristics has a different relationship to actual remaining work.

Consider a common case: a client-side data transformation that processes records in batches. The ring is driven by processed / total. If the expensive part of the work is not the per-record transformation but a final merge, index build, or serialization pass, then the ring will hit ninety percent and then sit there for as long as it took to reach ninety. Engineers learn this pattern the hard way, and they learn to distrust the last ten percent. But the more damaging lesson is subtler: they also learn to distrust the first sixty, because the ring's early confidence was never earned.

This is where the behavioral literature is genuinely useful rather than decorative. Daniel Kahneman and Amos Tversky's work on anchoring showed that an arbitrary starting number pulls subsequent estimates toward it, even when people know the number is arbitrary. A ring at sixty is an anchor. It tells the team that the work is "mostly done," which makes the remaining forty feel like a short tail rather than a second project. When the tail turns out to be long, the natural response is not to recalibrate the denominator — it is to conclude that the denominator was wrong, and therefore the whole approach was wrong. That conclusion is frequently premature.

There is a second effect at play, and it is the one that makes rebuilds feel so attractive. Loss aversion, also from Kahneman and Tversky, describes the asymmetry between the pain of losing something and the pleasure of gaining the same thing. In a debugging context, the "loss" is the sixty percent already invested. Continuing to debug means risking that investment on an uncertain fix. Rebuilding means writing off the investment cleanly and starting from a state where nothing is at risk yet. The rebuild feels like a fresh start precisely because it converts a sunk cost into an accounting decision rather than a technical one.

Why sixty percent is the specific trigger

Not every progress value produces the same behavior. Ten percent is too early to abandon — there is no investment to protect. Ninety percent is too late — the sunk cost is overwhelming and the finish line is visible. Sixty is the inflection point where both forces are strong: enough invested to hurt, enough remaining to imagine a better path.

This maps onto a well-documented pattern in decision-making under uncertainty. When people face a choice between continuing a course of action and switching, the probability of switching peaks not at the beginning and not at the end, but somewhere in the middle. The middle is where the evidence is ambiguous, the cost of continuing is salient, and the alternative is still abstract enough to look clean. A rebuild at sixty percent is attractive because nobody has yet had to debug the rebuilt version. The new architecture exists only as a diagram, and diagrams do not have race conditions.

There is a competitive dimension here too, and it is worth naming because it shapes engineering culture more than most people admit. Teams compare velocity. A rebuild is legible as progress in a way that debugging rarely is: it produces new files, new diagrams, new commit history. Debugging produces a fix that may be a two-line change after three days of investigation, which looks like nothing in a diff and feels like nothing in a standup. The reward loop favors visible construction over invisible repair. If you have ever wondered why your organization keeps rewriting the same service every eighteen months, this is a large part of the answer.

Variable-ratio reinforcement — the schedule where a reward arrives after an unpredictable number of attempts — is the classic mechanism behind persistent, sometimes compulsive behavior. Debugging is a variable-ratio task. You do not know how many hypotheses you will test before one holds. That unpredictability is motivating in small doses and corrosive in large ones. A rebuild replaces the variable-ratio loop with a fixed-ratio one: write these modules, wire these interfaces, ship. The certainty is psychologically relieving even when it is technically worse. Engineers are not optimizing for expected value alone; they are optimizing for a tolerable emotional schedule.

What the rebuild actually costs

The 31 percent figure in the title is not a law of nature, but it is a useful stand-in for a pattern that shows up repeatedly in post-mortems and engineering retrospectives: rebuilds tend to take longer than the estimate by a margin that is itself underestimated. The reasons are structural, not personal.

First, the original system encodes knowledge that is not written down. Every awkward conditional, every strange retry, every comment that says "do not remove" is a compressed record of a bug that someone already paid for. A rebuild starts by discarding that record and then rediscovering it, one incident at a time. The rediscovery is not optional; the bugs are still there in the requirements, waiting to be reintroduced.

Second, the rebuild's scope grows during the rebuild. This is not scope creep in the pejorative sense. It is that a new system makes new things possible, and once those things are visible, they become requirements. The old system's limitations were invisible because nobody could see past them. The new system's limitations are visible immediately, because the architecture invites comparison.

Third, and least discussed, the rebuild resets the team's calibration. The people who understood the old system's failure modes are now working in a system whose failure modes are unknown. Debugging ability is domain-specific. A team that could diagnose the old system in twenty minutes may need weeks to reach the same fluency in the new one. That cost never appears in the estimate because it is not a task; it is a capability, and capabilities are not line items.

A concrete illustration: a Croatian SaaS team maintaining a booking flow for small hospitality operators once faced a progress ring stuck at sixty percent during a nightly availability recalculation. The recalculation was slow, the ring was accurate, and the team concluded the algorithm was fundamentally wrong. They rebuilt it over five weeks. The new version was faster in isolation and slower in production, because the old version had been quietly caching partial results across requests in a way that no one had documented. The rebuild restored correctness and lost the cache. The fix that would have addressed the original problem was a memoization layer of roughly forty lines. Nobody wrote it, because at sixty percent the ring made the algorithm look like the problem rather than the symptom.

Reading partial signals without panicking

The practical question is not whether to rebuild. Sometimes the answer is yes, and defending a doomed architecture out of sunk-cost loyalty is its own failure mode. The question is how to make the decision without letting the ring do the deciding.

Separate the indicator from the model. Before acting on a progress signal, ask what it is actually counting and what it is not. If the ring is driven by task count rather than cost, it is measuring bookkeeping, not work. Write down the denominator explicitly. If nobody can state it in one sentence, the ring has no authority and should not be treated as evidence.

Instrument the tail. The last ten percent of a long task is where the surprises live, and it is also where instrumentation is cheapest. Add timing around the phases that the ring does not distinguish. A ring that says sixty percent while a profiler says "eighty percent of wall time is in the final merge" is telling two different stories, and the profiler is the one to believe.

Time-box the investigation before deciding. A fixed interval — two days, a week, whatever the context supports — converts an open-ended question into a bounded one. If the root cause is found within the box, you debug. If it is not, you have real information: the problem is not shallow, and the rebuild case is stronger. The point is to make the decision on evidence rather than on the emotional texture of the ring.

Name the sunk cost out loud. Loss aversion operates best in silence. A team that says "we have spent three weeks on this and that spending is gone regardless of what we choose next" is measurably better at evaluating the forward options. The three weeks are not a reason to continue and not a reason to abandon. They are simply spent.

Watch for the rebuild as mood repair. If the motivation for rebuilding is that debugging feels bad, that is worth knowing. It does not automatically make the rebuild wrong, but it changes what you should do next: you should ask whether the team has the instrumentation and the time to debug at all, because if not, the rebuild will eventually present the same problem in a new codebase, and the cycle will repeat.

Designing interfaces that do not lie

There is a forward-looking version of this problem that is more interesting than the retrospective one. Progress indicators are an interface decision, and interface decisions shape behavior. A ring that claims precision it does not have will produce bad engineering decisions at scale, across teams, for years. The fix is not to remove progress indicators. It is to design them so that their uncertainty is visible.

Indeterminate progress — a spinner without a percentage — is honest but unhelpful for long tasks. A better pattern is phase-based reporting: instead of one ring at sixty percent, show which phase is active and how many phases remain, with the understanding that phases are not equal in cost. This is less satisfying to watch and more accurate to reason about. It also removes the anchoring effect, because there is no single number to anchor on.

A second pattern is to report elapsed time alongside progress, and to show the historical distribution of completion times for similar tasks. "This usually takes four to twelve minutes" is a far more useful statement than "sixty percent," because it communicates variance rather than a false midpoint. It also gives the engineer a basis for deciding whether the current run is anomalous or normal, which is exactly the judgment the ring currently obscures.

A third pattern, and the one most likely to change behavior, is to make the cost model inspectable. If the ring is computed from a cost model, expose the model. Let the engineer see that the final serialization pass is weighted at thirty percent of total cost, even though it represents one percent of records. That single piece of information prevents a large fraction of the rebuild decisions described here, because it converts an opaque signal into a legible one. Opacity is what makes sixty percent feel like a verdict. Legibility turns it back into a measurement.

None of this eliminates the underlying tension. Debugging is uncertain, rebuilds are legible, and teams under pressure will keep choosing legibility. But the tension is manageable when the signals are honest, and it becomes corrosive when they are not. The next time a ring sits at sixty percent, the useful question is not "should we rebuild?" It is "what is this number actually telling us, and what is it hiding?" The answer to that question usually makes the next decision obvious — and occasionally, it makes it obvious that the rebuild was the right call all along, for reasons the ring never could have shown.