Side by side
DebouncevsThrottling
What is the difference between debounce and throttle?
Updated 2 min read7 differences
In short
Debounce waits until a burst of events stops, then runs the function once, while throttle runs it at most once per interval as the events continue.
Debounce
Debouncing delays a function until a burst of events has paused for a set time, so a search box sends one request after typing stops, not one per keystroke.
Read the page on DebounceThrottling
Throttling makes a function run at most once per interval, however often it is called, so scroll and resize handlers update steadily without running every time.
Read the page on ThrottlingDebounce and Throttling compared
| Aspect | Debounce | Throttling |
|---|---|---|
| When it runs | Once, after the events stop for the wait time | Regularly, at most once per interval, during the events |
| During a long burst | Doesn't run at all | Runs again and again at a steady pace |
| First run | Only after the wait that follows the last event | Straight away, on the first call |
| Best for | Search as you type, autosave, validation, the end of a resize | Scrolling, dragging, progress updates, resizing as it happens |
| Typical timing | A wait of 200 to 500 ms | An interval of 50 to 200 ms, or one animation frame |
| Risk | Feels slow if the wait is too long | Can miss the final state without a last, trailing call |
| Helpers | debounce in Lodash and similar libraries | throttle in the same libraries, or requestAnimationFrame |
The difference, explained
Both tame functions that would otherwise run on every keystroke, scroll step or resize. Debounce restarts a timer on every event and runs the function only after the events have been quiet for the whole wait, say 300 milliseconds. Throttle runs the function, then ignores calls until the interval has passed, so during a long burst it runs regularly, say every 100 milliseconds.
The difference shows when the user keeps going. Typing a ten-letter search with a 300 ms debounce sends one request, after the last letter; with a 300 ms throttle it sends several while the user is still typing. Scrolling for three seconds with a debounced handler updates nothing until the scrolling stops; a throttled one updates steadily the whole time.
So the choice follows from what the user needs to see. If only the final value matters, as in search, autosave, form validation or recalculating a layout after a resize, debounce. If the screen should keep up with the action, as in infinite scroll, a progress bar, a shrinking header or dragging, throttle. Some helpers offer a debounce with a maximum wait, which combines the two: it waits for a pause but still runs every so often.
Neither makes the work faster; both make it happen less often, and both add some delay. For animation, requestAnimationFrame is often better than either, since it runs once per frame, in step with the screen.
Which one should you use?
Choose Debounce when…
- Only the final value matters, as in a search box or autosave.
- The work is expensive, such as a network request, and should run once per pause.
- Running during the action would show results the user has already moved past.
Choose Throttling when…
- The user should see updates while scrolling, resizing or dragging.
- A long, continuous action must still trigger work regularly.
- You need a firm upper limit on how often the work runs.
A debounced search box and a throttled scroll handler
// Debounce: one request after the user stops typing
search.addEventListener("input", debounce((event) => {
fetchResults(event.target.value);
}, 300));// Throttle: check the position at most every 100 ms while scrolling
window.addEventListener("scroll", throttle(() => {
header.classList.toggle("compact", window.scrollY > 80);
}, 100));Readers ask
Which one should I use for a search box?
Debounce. The user cares about results for what they finally typed, and one request after a short pause spares the server many requests for half-typed words.
Which one should I use for scroll events?
Throttle, or requestAnimationFrame if you are updating something on screen. A debounced scroll handler does nothing until the user stops scrolling.
Can I use both together?
Yes. Some helpers offer a debounce with a maximum wait: it waits for a pause, but runs anyway if the events go on longer than the limit. That suits autosave during long editing sessions.