~/ Dev Notes

Jun 12, 2026 · 1 min

Debounce vs. throttle, and when I reach for each

Two functions that look identical in the docs and behave nothing alike in production.

#javascript#perf

Every few months I confuse these two, write the wrong one, and ship a janky scroll handler. So here is the version of the explanation that finally stuck for me.

The one-line difference

Debounce waits for quiet. Throttle enforces a rhythm. That’s it. If you remember nothing else, remember that a debounced function fires after things stop happening, and a throttled function fires at a steady cadence while things keep happening.

Search-as-you-type wants debounce — you don’t care about every keystroke, you care about the pause. A scroll or resize handler wants throttle — you want regular updates, just not 200 of them a second.

function debounce(fn, ms) {
  let t;
  return (...args) => {
    clearTimeout(t);
    t = setTimeout(() => fn(...args), ms);
  };
}

The mistake I keep making

Reaching for debounce on a scroll handler. The page feels dead until you stop scrolling, then everything snaps into place at once. Throttle would have kept it alive the whole way down.

Rule of thumb: if the user is waiting for you to stop, debounce. If the user is watching something move, throttle.