Debounce vs Throttle: Differences, Use Cases, and Implementations

Interview-ready guide to debounce vs throttle: how they work, when to use each, and clean JavaScript implementations (with leading/trailing options).

F

Frontend Interview Team

February 08, 2026

~14 min
Debounce vs Throttle: Differences, Use Cases, and Implementations

Debounce and throttle are common interview questions because they show whether you understand:

  • performance in the browser
  • event handling
  • timing control

They’re also extremely practical.


30‑second interview answer

Debounce delays execution until events stop firing for X ms (great for search input). Throttle runs at most once every X ms (great for scroll/resize). Debounce reduces calls by waiting for a pause; throttle reduces calls by enforcing a max rate.

Key points

  • Debounce = “wait for quiet”.
  • Throttle = “limit the rate”.
  • Decide based on whether you want the final value or continuous updates.

1) The difference (one-liner)

  • Debounce: “Only run after the event stops firing for X ms.”
  • Throttle: “Run at most once every X ms.”

2) When to use Debounce

Use debounce when you want the final result after the user pauses:

  • search input (typeahead)
  • resizing a window (final layout calc)
  • autosave after typing stops

Example

input.addEventListener('input', debounce((e) => {
  search(e.target.value);
}, 300));

3) When to use Throttle

Use throttle when you want updates during continuous activity, but not too frequently:

  • scroll events (infinite scroll)
  • mousemove (dragging)
  • analytics pings

Example

window.addEventListener('scroll', throttle(() => {
  trackScroll();
}, 200));

4) Debounce implementation (simple)

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

Interview notes

  • we clear the previous timer
  • only the last call survives
  • this and args are preserved via apply

5) Throttle implementation (simple)

export function throttle(fn, interval = 200) {
  let lastTime = 0;
 
  return function (...args) {
    const now = Date.now();
 
    if (now - lastTime >= interval) {
      lastTime = now;
      fn.apply(this, args);
    }
  };
}

This is a "leading" throttle (runs immediately on first trigger).


6) More complete versions (leading/trailing)

Interviewers sometimes ask for options.

Debounce with leading option

export function debounceAdvanced(fn, delay = 300, { leading = false } = {}) {
  let timer;
  let invoked = false;
 
  return function (...args) {
    if (leading && !invoked) {
      fn.apply(this, args);
      invoked = true;
    }
 
    clearTimeout(timer);
    timer = setTimeout(() => {
      invoked = false;
      if (!leading) fn.apply(this, args);
    }, delay);
  };
}

Throttle with trailing call

export function throttleAdvanced(fn, interval = 200) {
  let lastTime = 0;
  let timer;
  let lastArgs;
  let lastThis;
 
  return function (...args) {
    const now = Date.now();
    lastArgs = args;
    lastThis = this;
 
    const remaining = interval - (now - lastTime);
 
    if (remaining <= 0) {
      clearTimeout(timer);
      timer = undefined;
      lastTime = now;
      fn.apply(lastThis, lastArgs);
      return;
    }
 
    // schedule a trailing call
    if (!timer) {
      timer = setTimeout(() => {
        lastTime = Date.now();
        timer = undefined;
        fn.apply(lastThis, lastArgs);
      }, remaining);
    }
  };
}

7) Common interview Q&A

Q: Is debounce or throttle better for search input?

  • Debounce. You typically want the final value after the user pauses typing.

Q: What about scroll handler?

  • Throttle. You want periodic updates while scrolling.

Q: Can you debounce a promise-returning function?

  • Yes, but you should decide what happens to previous pending promises (often you cancel with AbortController).

Summary checklist

  • I can define debounce vs throttle.
  • I know when to use each (search vs scroll).
  • I can explain leading vs trailing.
  • I can implement both.

Summary

  • Debounce = run after quiet period.
  • Throttle = run at most once per interval.
  • Both are used to protect performance on hot events like input/scroll/mousemove.