Developer's Guide to ETA Calculator: Best Practices and Examples
August 18, 2026 · The Devs Tools Team
Estimating how long a task has left to run — a file transfer, a batch job, a data migration — comes down to a simple ratio at its core: given how much work has been completed in a known amount of elapsed time, project the rate forward across the remaining work. If you've processed 2,400 of 10,000 records in 90 seconds, your rate is roughly 26.7 records/second, and the remaining 7,600 records should take about 285 seconds at that same rate. This is a linear extrapolation, and it's the basis of nearly every progress bar's "time remaining" display — but it's also where most ETA estimates go wrong, because real-world task rates are rarely constant. A file copy might start fast (small files, OS caching) and slow down dramatically on a handful of large files near the end; a network transfer's throughput fluctuates with congestion; a batch job might have a fixed per-item processing cost plus periodic overhead (garbage collection, I/O flushes, connection re-establishment) that shows up as intermittent stalls rather than a smooth rate. A naive ETA calculated once at the start and never updated will drift further from reality as the task progresses, which is why more robust implementations recompute the rate continuously using only a recent sliding window of progress — smoothing out momentary slowdowns while still adapting when the true throughput shifts meaningfully, rather than being permanently anchored to an initial burst of speed that isn't representative of the whole task.
[!TIP] Need to estimate a completion time right now? Try our free, local ETA Calculator to compute remaining duration from elapsed time and progress completely offline.
The Core Formula
rate = completed_items / elapsed_time
remaining_time = (total_items - completed_items) / rate
Or expressed purely in terms of percentage complete:
remaining_time = elapsed_time * (1 - percent_complete) / percent_complete
Both are mathematically equivalent — pick whichever inputs you naturally have available (raw item counts vs. a percentage).
Why Naive ETAs Feel Wrong
A progress bar that estimates "2 minutes remaining" and then sits at that estimate for five minutes is a common and irritating UX failure. It usually happens because:
- The estimate was computed once, early, from an unrepresentative burst of speed (e.g. small files processed first).
- The task has a non-linear cost curve — some phases (indexing, finalizing, committing) are inherently slower than the bulk of the work and don't fit the same rate.
- Network or disk I/O throughput varies enough that a single instantaneous rate sample is noisy.
A More Stable Approach
Recompute the rate periodically using only recent progress, rather than the full history since the task began:
// Sliding window: only consider progress from the last N seconds
const recentRate = (currentCount - countNSecondsAgo) / windowSeconds;
const eta = (totalCount - currentCount) / recentRate;
This adapts faster to genuine slowdowns or speedups while damping noise from any single slow tick.
Practical Applications
- File upload/download progress bars
- Batch data processing or migration jobs
- Build/CI pipeline step duration prediction
- Physical progress estimates (e.g. print jobs, render jobs) based on units completed per unit time
Conclusion
An ETA is only as good as the assumption that past rate predicts future rate — true for steady, uniform workloads, and misleading for anything with phase changes or bursty throughput. Recomputing from a recent window rather than the whole task history, and being honest that an ETA is an estimate rather than a promise, produces numbers that are far more useful in practice.
