Debounce and throttle are two core JavaScript performance optimization techniques for controlling how often a function runs in response to frequent events like typing, scrolling, or resizing. A very common frontend interview question is designing a live search input: should you debounce or throttle the API call, and is 200ms a good debounce value?
Debounce vs Throttle in JavaScript: Which One Should You Use for Search Inputs?
Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.
The real interview problem
This question is not about definitions. It's about this:
"How do you prevent expensive work from running too often when the user types?"
Typing in a search input can easily trigger 10–20 events per second. Calling an API on each keystroke is wasteful, slow, and can even get you rate-limited.
Debounce vs Throttle — the mental model
Technique | Mental model | What it does |
|---|---|---|
Debounce | "Wait until the user stops typing" | Runs the function only after no events happened for N ms |
Throttle | "Run at most once every N ms" | Runs the function at a fixed maximum rate |
Which one should you use for search?
Almost always: Debounce.
Why?
- You only care about the final query
- Intermediate keystrokes produce useless requests
- Debounce waits until the user pauses, then sends one clean request
Is 200ms a good debounce value?
Usually yes — as a starting point.
- Common range: 150–300ms
- 200ms often feels instant to humans
- But still cuts request volume massively
Trade-off:
- Too small → still spams API
- Too big → UI feels laggy
Senior answer: "We should measure and tune this based on UX and backend cost."
Simple debounce implementation
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
const onSearch = debounce((query) => {
fetch(`/api/search?q=${query}`);
}, 200);
The real-world bug: race conditions
Even with debounce, this can happen:
1) User searches "rea"
2) Then quickly searches "react"
3) The "rea" request returns after the "react" request
4) UI shows wrong results
Solution:
- Cancel in-flight requests (AbortController)
- Or track request IDs and ignore stale responses
When should you use throttle instead?
Throttle is better for continuous signals:
- Scroll handlers
- Resize events
- Mouse move / drag
- Analytics sampling
In those cases you want regular updates, not just the final value.
Common mistakes
- Using throttle for search → sends half-baked queries
- Debouncing too aggressively → UI feels broken
- Not cancelling previous requests
- Letting stale responses overwrite fresh ones
One-sentence interview answer
"For search inputs I would use debounce, not throttle, because I only care about the final query — and ~200ms is a good starting point that should be tuned based on UX and backend cost, plus I’d handle request cancellation to avoid race conditions."