Debounce and Throttle

Two tiny functions to control how often a handler runs — with the difference explained.

~1 min read updated Jul 17, 2026 Snippets
  • #javascript
  • #performance
  • #snippets
  • #events

Both limit how often a function runs. Debounce waits until the activity stops; throttle runs at a steady maximum rate.

Debounce

Runs once, after things go quiet. Ideal for search-as-you-type or validating a field after the user stops typing.

function debounce(fn, delay = 300) {
  let timer
  return (...args) => {
    clearTimeout(timer)
    timer = setTimeout(() => fn(...args), delay)
  }
}

const onSearch = debounce(query => fetchResults(query), 300)
input.addEventListener('input', e => onSearch(e.target.value))

Throttle

Runs at most once per interval. Ideal for scroll and resize handlers that would otherwise fire hundreds of times a second.

function throttle(fn, interval = 200) {
  let last = 0
  return (...args) => {
    const now = Date.now()
    if (now - last >= interval) {
      last = now
      fn(...args)
    }
  }
}

window.addEventListener('scroll', throttle(updateProgressBar, 100))
Rule of thumb: debounce when you only care about the final state (the last keystroke), throttle when you want regular updates during a continuous action (scrolling).

Related notes