Lodash _.debounce() method

Beginner
⏱️ 8 min read
📚 Updated: May 2026
🎯 3 Code examples
🚀 3 Try-it labs
Lodash

What you’ll learn

  • How debounce delays expensive work until input events settle.
  • How leading, trailing, and maxWait affect scheduling.
  • When to call cancel() and flush() in real UI lifecycles.
  • How it differs from _.throttle for continuous streams.

Prerequisites

Recommended: _.curryRight() for wrapper basics and the Function hub for timing context.

  • Event loops: knowing that timers run later, not inline.
  • UI cleanup: cancel pending handlers on unmount/navigation.

Overview

_.debounce(func, wait, options) returns a wrapper that waits for inactivity before invoking func. It tracks the latest arguments, supports leading/trailing edge control, and exposes cancel() and flush().

Syntax

javascript
_.debounce(func, [wait=0], [options])
  • func: callback to debounce.
  • wait: milliseconds to wait after the last call.
  • options: leading, trailing, and optional maxWait.
  • returns: debounced function with cancel and flush methods.
1

Default trailing debounce

Three rapid calls run func once after the wait window.

javascript
import debounce from "lodash/debounce";

let runs = 0;
const save = debounce(() => { runs += 1; }, 120);

save();
save();
save();

setTimeout(() => console.log(runs), 160);
// 1
2

Leading only

With { leading: true, trailing: false }, first call in a burst runs immediately.

javascript
import debounce from "lodash/debounce";

let runs = 0;
const clickOnce = debounce(() => { runs += 1; }, 200, {
  leading: true,
  trailing: false
});

clickOnce();
clickOnce();
clickOnce();
console.log(runs);
// 1
3

cancel() and flush()

Cancel prevents pending trailing execution; flush runs it immediately.

javascript
import debounce from "lodash/debounce";

const log = [];
const push = debounce((v) => log.push(v), 300);

push("A");
push.cancel(); // A never runs

push("B");
push.flush(); // runs now

console.log(log);
// ["B"]

📋 _.debounce vs _.throttle

HelperBest forBehavior
_.debounceSearch input, autosaveWait for quiet period
_.throttleScroll/resize streamsRun at most once per interval

Pitfalls to avoid

Cleanup

Forgotten cancel

Pending handlers can run after component teardown unless cancelled.

Options

leading + trailing confusion

Trailing with both true only fires if the wrapper is called multiple times during wait.

Long streams

No periodic updates

Use maxWait when constant events must still emit at intervals.

❓ FAQ

It delays calling func until wait milliseconds pass since the most recent wrapper call. Repeated calls reset the timer.
cancel() clears pending trailing execution, while flush() runs a pending trailing call immediately and returns its result.
leading runs immediately at the start of a burst; trailing runs after the burst ends. If both are true, trailing only happens when there is more than one call in the wait window.
Use maxWait for long continuous event streams so func still runs periodically even if calls never pause.
debounce waits for quiet time before invoking. throttle enforces a maximum rate and keeps invoking during the stream.

Summary

  • Purpose: debounce delays work until calls stop for a configured interval.
  • Controls: leading/trailing/maxWait plus cancel() and flush().
  • Next: Lodash _.defer() or compare with _.throttle().
Did you know?

Lodash stores the latest arguments and returns the last invocation result from the debounced wrapper; with both leading and trailing enabled, trailing fires only when the wrapper is called more than once during the wait window.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful