Progress Bar
ETA Computation
Smart Algorithms
Time Estimation
User Experience

Smart progress bar ETA computation

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

A progress bar becomes much more useful when it shows a believable ETA instead of a wildly fluctuating guess. The hard part is that many tasks do not run at a constant speed. Download rates change, CPU work arrives in bursts, and some steps are inherently more expensive than others. A smart ETA therefore needs smoothing, not just a naive division of remaining work by the most recent speed.

The Naive ETA Formula

If a task reports done units out of total units and has been running for elapsed seconds, the simplest ETA is:

eta = (total - done) / current_rate

where current_rate = done / elapsed.

That works for steady workloads, but it becomes unstable when progress is bursty. Early in the task, one fast or slow sample can produce ridiculous estimates.

Use A Smoothed Rate Instead Of An Instant Rate

A common improvement is an exponentially weighted moving average, often shortened to EWMA. Instead of trusting the latest speed sample completely, blend it with earlier samples.

python
1import time
2
3class ProgressETA:
4    def __init__(self, total, alpha=0.2):
5        self.total = total
6        self.alpha = alpha
7        self.start_time = time.time()
8        self.last_time = self.start_time
9        self.last_done = 0
10        self.smoothed_rate = None
11
12    def update(self, done):
13        now = time.time()
14        delta_time = now - self.last_time
15        delta_done = done - self.last_done
16
17        if delta_time > 0 and delta_done >= 0:
18            instant_rate = delta_done / delta_time
19            if self.smoothed_rate is None:
20                self.smoothed_rate = instant_rate
21            else:
22                self.smoothed_rate = (
23                    self.alpha * instant_rate
24                    + (1 - self.alpha) * self.smoothed_rate
25                )
26
27        self.last_time = now
28        self.last_done = done
29
30        if not self.smoothed_rate or self.smoothed_rate <= 0:
31            return None
32
33        remaining = max(self.total - done, 0)
34        return remaining / self.smoothed_rate

This makes the ETA calmer and much more believable for human users.

Delay ETA Until You Have Enough Signal

Another good trick is to hide the ETA during the first few updates. A progress bar that says "2 hours remaining" after one second and then changes to "12 seconds remaining" looks broken even when the code is mathematically correct.

A practical rule is:

  • show percentage immediately n- wait for a few progress updates before showing ETA
  • suppress ETA if progress has stalled or rate is too noisy

That gives the progress bar time to learn a useful speed estimate.

Think In Real Units, Not Only Percent

The ETA should be based on real work units when possible:

  • bytes downloaded
  • files processed
  • rows imported
  • steps completed

That is better than estimating from percentage alone, because different percentages may represent very different amounts of work.

For example, if you know file size during a download, bytes per second is a much better basis than visual progress percentages.

Handle Non-Linear Tasks Explicitly

Some tasks are not uniform. Parsing a small file and parsing a huge file may each count as one completed item, but their durations are not remotely equal.

In that case, a smart ETA may need weighted progress or phase-aware reporting. For example:

  • phase 1 scans metadata
  • phase 2 downloads data
  • phase 3 performs local indexing

If you treat all phases as identical units, the ETA will jump badly. If you report each phase separately or assign weighted progress, the estimate becomes more honest.

Common Pitfalls

The most common mistake is recomputing ETA from the most recent sample only. That makes the display jump around and erodes user trust.

Another issue is showing ETA too early, before the rate estimate has stabilized. Hiding the estimate briefly is often better UX than showing nonsense.

It is also easy to ignore stalled work. If no progress has been made for a while, keep the last stable ETA carefully or display an "estimating" message instead of dividing by nearly zero.

Finally, do not confuse a mathematically precise number with a useful user-facing estimate. A calm approximate answer is often better than a noisy exact one.

Summary

  • A smart progress bar ETA should be based on work rate, not only percent complete.
  • Smoothed rates such as EWMA produce better estimates than raw instant speed.
  • Delay ETA display until enough progress samples exist.
  • Use real task units such as bytes or records whenever possible.
  • Non-linear tasks often need weighted or phase-aware progress reporting.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.