Progress-bar estimates
A Socratic walk-through of progress-bar estimates — reasoned out one step at a time, not lectured.
The question we started with
THE QUESTION #Why does a progress bar race to ninety percent and then crawl for the rest?
The bar sprints across the dialog, hits ninety percent in eight seconds, and then sits there. Two minutes later it is at ninety-four, and the estimate underneath has said "about 30 seconds remaining" for four straight minutes — a claim now wrong roughly eight times in a row.
The easy verdict is that the programmer was lazy. But consider what would have to be true for the bar to be right: it would have to know how long the remaining work takes, and if the program knew that, it would usually already know the answer it is currently computing. So the interesting question is not why it is wrong, but what exactly it is measuring and what that measurement assumes.
Reasoning it through
REASONING #Start with what the program actually has. A count of units — files, records, bytes, steps — and how many are done. A clock. From those two it computes a rate, units per second so far, and the estimate falls out of a single division: time remaining equals units remaining divided by that rate.
Now put the assumption under a light. That division is valid only if the next unit costs about what the last ones did. Two things must hold: the units must be alike, and the rate must be stable over time. Is either true of a real job?
Take a folder copy: three thousand small files and one four-gigabyte video. The counter says four percent complete after a hundred and twenty small ones, done in a second, so the projected rate is enormous and the estimate delightful. Then it reaches the video. Nothing about the counter is dishonest; the unit was the wrong thing to count, because file count and file cost are not proportional. The estimate was a projection from a sample that did not represent what was left.
Now the rate. A download starts on a warm cache, or an uncongested link at two in the morning, then hits a slow hop, a throttle, an overloaded server. Even with identical units the rate is not a constant to be measured; it is a process that moves. Statistically the estimator is extrapolating linearly from a non-stationary series — and the error is worst precisely at the end, because no remaining work is left over which the projection can correct itself.
A third contributor produces the specific ninety-percent stall: a great deal of real work is not in the counter at all. The bytes are copied — and then the system flushes buffers to disk, verifies checksums, rebuilds an index, updates a registry, releases locks. That work has no natural unit and often no way to be measured in advance, so it gets a token slice of the bar or none. The bar sits at ninety-nine percent doing something real it never budgeted for.
Which explains the asymmetry. Why stall at the end and never at the start? Partly because a job front-loads its cheap uniform work and back-loads the expensive irreducible step. But also because of a selection effect in what we notice: a too-pessimistic estimate gets corrected quietly as the job proceeds and is never remembered, while a too-optimistic one is discovered at the end and has nowhere to hide.
And now the honest part most explanations omit. Progress bars are not only instruments; they are interface elements, and human-factors researchers have shown that the shape of the bar's motion changes how long the wait feels, independently of its actual length. Chris Harrison and colleagues found that bars whose apparent speed increases toward the end are perceived as shorter than bars covering the same real duration at a steady pace. Designers know this. So some of the curve you are watching is not an estimate at all — it is a chosen animation, tuned for perceived duration rather than accuracy.
The analogy
THE ANALOGY #Think of estimating your arrival from your average speed so far. Twenty miles of empty motorway at seventy, and the arithmetic says four o'clock. The arithmetic is not wrong; it answers a different question — when would I arrive if the rest were like this? — and the rest is town centre, a level crossing, and ten minutes hunting for a parking space that the map counted as zero distance.
A driver has independent knowledge of the route and can see the town coming, whereas a progress bar usually has no model of what is left at all — it knows how many units remain, not that the last one is the video file.
Clarifying the model
THE MODEL #Three refinements tie the reasoning together.
First, the bar is a proxy. It shows work-units completed and we read it as time elapsed, and those are equal only when every unit costs the same. Almost no interesting job has that property. The bar is not lying about the thing it measures; we are misreading which thing that is.
Second, this is improvable, not fixable. A copier can weight by bytes rather than files; an installer can time its phases on previous runs; a well-built job can reserve explicit slices for finalisation. Each buys real accuracy. But some remaining work genuinely cannot be estimated in advance — how long a remote server will take, how long a flush will take under whatever else the machine is doing — and no amount of care removes that.
Third, accuracy is not the only goal, which reframes the whole complaint. Progress indicators were shown in Brad Myers's early experiments to be preferred by users even when displaying them made the task slower — their job is to signal aliveness and bound uncertainty, not to forecast. Which is why an indeterminate spinner is sometimes the more honest choice: it makes no numeric claim, and a wrong numeric claim costs more trust than none.
A picture of it
THE PICTURE #How to readStart at the rounded terminal and follow the single computation the bar performs: units counted, completions stored, a uniform rate assumed in the six-sided preparation node, and one division producing the number shown. The diamond is where reality intervenes — take the left branch when the remaining units resemble the finished ones, and either right-hand branch when they do not. Both failure branches loop back to the completion store, which is the vicious part: each redraw recomputes from the same unrepresentative history, so the bar keeps confidently reprojecting a rate it no longer has.
What became clearer
WHAT CLEARED #A progress bar does not measure time; it measures units of work and divides. That division silently assumes the remaining work resembles the finished work and that the rate is stable — neither of which holds for a job with a large file at the end, a congested link in the middle, or a flush that was never counted at all. The estimate is a projection from a non-stationary process, and the final stretch is exactly where it has no room left to correct itself. Some of the curve, meanwhile, was chosen by a designer who knew that how the bar moves changes how long the wait feels.
Where to go next
ONWARD #- Why software schedules fail in the same shape, and what the planning fallacy adds to the mechanism.
- When an indeterminate spinner is the more honest interface than a numeric bar.
Key terms
TERMS #| Term | What it means |
|---|---|
| Non-stationary process | one whose statistical behaviour, such as its mean rate, changes over time, so past averages do not predict future values. |
| Proxy measure | a quantity that stands in for the one you actually care about, accurate only while the relationship between them holds. |
| Indeterminate progress indicator | a spinner or looping animation that signals activity without claiming a completion percentage. |
Every term the collection defines is gathered in the glossary.