Designing progress people can trust
A progress bar is a promise. It tells the user that the system understands the work, is still responsive, and can estimate what remains. When that promise is inaccurate, the interface feels less trustworthy than showing no estimate at all.
Count before claiming certainty
Some operations do not know their total size at the beginning. File transfers are a common example. A quick scan can establish the number of files and bytes before the transfer begins, allowing the main progress indicator to reflect real work instead of an animation.
The scan adds a small initial cost, so the interface should explain that phase rather than appearing frozen.
Smooth the noisy numbers
Instantaneous transfer speed changes constantly. Updating it on every chunk creates visual noise and makes the estimated time jump around. A short rolling window produces a value that still feels live without being distracting.
The update interval also matters. Rendering dozens of updates per second rarely improves understanding. A few measured updates each second are usually enough.
Cancellation is a workflow
A cancel button needs a clear contract. Can the process stop immediately? Will partial files remain? Can the operation be resumed? The interface should answer these questions before the user has to discover them through failure.
Backend cleanup is part of the feature. Child processes need to be terminated and awaited, temporary state must be released, and the final UI state should distinguish cancellation from an error.
Prefer honest states
Useful progress interfaces expose a small vocabulary: preparing, running, paused, cancelling, complete, and failed. Each state has a clear next action. This is more valuable than decorative animation because it reduces uncertainty during the moments when users are already waiting.