Debouncing AI Calls

Wait for the user to stop typing before calling the AI, so you fire one request instead of dozens.

TL;DR

  1. Wait until typing pauses before firing the request.
  2. Skip empty, short, or unchanged input values.
  3. Combine debounce with cancellation to drop stale calls.

Debounce the Input

    Set a Timer

    Wait a beat after the last keystroke.

    const id = setTimeout(() =>
      setDebounced(value), 400);
    Clear on Change

    Cancel the pending timer each keystroke.

    return () => clearTimeout(id);
    Use the Delayed Value

    Act on the settled value, not the raw one.

    useEffect(() => { ask(debounced); },
      [debounced]);

A useDebounce Hook

    Reusable Hook

    Wrap the pattern for any value.

    function useDebounce(v, ms = 400) {
      const [d, setD] = useState(v);
    Effect and Timer

    Update the value after the delay passes.

    useEffect(() => {
      const id = setTimeout(() => setD(v), ms);
      return () => clearTimeout(id);
    }, [v, ms]);
    Return the Value

    Give back the debounced value.

    return d;

Skip Wasteful Calls

    Minimum Length

    Ignore inputs too short to be useful.

    if (query.trim().length < 3) return;
    Skip Unchanged

    Do not re-ask the same question.

    if (query === lastRef.current) return;
    Guard Empty

    Never call the AI with a blank prompt.

    if (!query.trim()) return;

Trigger the Call

    Fire on Settle

    Call the AI when the debounced value changes.

    useEffect(() => { run(debounced); },
      [debounced]);
    Pair With Abort

    Cancel any earlier request first.

    controllerRef.current?.abort();
    One Request

    A whole sentence becomes a single call.

    // dozens of keystrokes -> 1 request

Tips

  1. Debounce around 300 to 500 milliseconds for chat inputs; short enough to feel instant, long enough to skip mid-word keystrokes.
  2. Store the debounced value in state with a useEffect timeout, then trigger the AI call from that value, not the raw input.

Warnings

  1. Do not call the AI on every onChange; a fast typist can fire dozens of paid requests for a single question.
  2. Clear the previous timeout on each keystroke, or overlapping timers will fire several requests at once.

In Practice

FAQ