What is Debouncing & Throttling?

Why Your App Fires 100 Requests When It Only Needs One

Ever typed into a search box and watched your browser slow to a crawl? Every single keystroke was firing an API call, hammering the server with requests for "h", "he", "hel", "hell", "hello." That's an app without debouncing, reacting to every tiny input instead of waiting for you to finish.

7 min read Updated 2026-04-06 By Hasan

Two Ways to Stop Overreacting

Think of your app like an elevator. People keep pressing the "door close" button. Without any control, the elevator would try to close the doors after every single press, stuttering open-closed-open-closed like a broken accordion. Debouncing is the smart elevator that thinks: "I'll wait until people stop pressing, then close the doors once." It resets its timer with every press. Throttling is the strict elevator that says: "I close the doors every 10 seconds, period. Press all you want in between, I'm ignoring you until my timer fires."
Without debouncing or throttling: Your app reacts to every single event. A user typing "hello" fires 5 API calls. Scrolling down a page fires hundreds of resize calculations per second. Dragging a slider sends 60 update requests in one second. The server gets flooded, the browser slows down, and the user sees laggy, janky behavior. You're burning through API limits, racking up costs, and making the experience worse, all because your code can't tell the difference between "the user is still going" and "the user is done."
With debouncing: The smart elevator waits until people stop pressing, then closes the doors once. Your debounced search box waits 300 milliseconds after the last keystroke before firing. The user types "hello" and only one request goes out. Same user experience, a fraction of the work. Your server breathes, your app feels snappy, and your API bill stays reasonable.
With throttling: The strict elevator runs on a schedule: "I close the doors every 10 seconds, period. Press all you want in between." Your throttled scroll handler fires once every 200 milliseconds instead of 60 times per second. It doesn't wait for silence like debouncing — it just enforces a steady rhythm. The first event fires immediately so it feels responsive, then a cooldown starts. Perfect for scroll events, resize handlers, and anything that fires continuously.
TL;DR

Debouncing = wait until the user stops acting, then fire once. Throttling = fire at most once every X seconds, no matter how often the user acts.

Note

Debouncing and throttling are frontend techniques. They reduce how often your code runs. Rate limiting (another Building Block) is the server-side version: it rejects requests that come in too fast. Think of debounce/throttle as the polite caller who waits before dialing, and rate limiting as the receptionist who hangs up on the 11th call per minute.

When to Use Debouncing & Throttling

Debouncing & Throttling isn't always the right call. Here's a quick mental model:

Search boxes or autocomplete fields

Users type fast. Debounce so you send one request after they pause, not one per keystroke

Scroll, resize, or drag events

These fire dozens of times per second. Throttle to run your handler at a sane rate (every 100-200ms)

Auto-save or form validation

Debounce so the save or validation triggers after the user stops editing, not while they're mid-sentence

You're hitting API rate limits or high costs

If your app sends too many requests and your server (or wallet) complains, debouncing the trigger is the cheapest fix

The action must happen instantly

A "Submit Order" button should fire immediately on click. Debouncing a checkout button would feel broken. Use it for background processes, not critical user actions

Events are already infrequent

If a button only gets clicked once every few seconds, there's nothing to debounce. Adding a timer just makes the app feel sluggish for no reason

Interactive Debouncing & Throttling Demo

Try both techniques side by side. First, simulate typing into a search box to see debounce in action. Then simulate rapid scroll events to see throttle at work.

Debouncing & Throttling Simulator

Simulated — no real calls
Part 1: Debounce — Search Box
⛔ Without Debounce
API Calls
✓ With Debounce (300ms)
API Calls
Part 2: Throttle — Scroll Handler
⛔ Without Throttle
Handler Calls
✓ With Throttle (200ms)
Handler Calls
What to notice:
  • Without debounce, every keystroke fires an API call — 11 calls for "hello world"
  • With debounce, only 1 call fires after you stop typing
  • Without throttle, all 30 scroll events trigger layout recalculations
  • With throttle, only a handful of calls get through — same smooth experience

AI Prompts for Debouncing & Throttling

Now that you understand debouncing & throttling, use these prompts with your AI coding agent. Copy the one that matches what you're building — the agent will handle the implementation.

Tip: These prompts work with any AI (ChatGPT, Claude, Cursor, Copilot). Just copy, paste, and fill in the [brackets]. You don't need to understand timer code. The AI will explain as it builds.

starter Start here. The most common debouncing use case
My [app / website] runs a function every time the user scrolls or resizes the window. It's making the page laggy because the function fires hundreds of times per second. Add throttling so the function runs at most once every [200ms / 100ms / 500ms]. Make sure: - The first event fires immediately (so it feels responsive) - The last event also fires (so the final position is captured) - The UI stays smooth during fast scrolling - I can easily adjust the throttle interval later My stack: [your framework and language here] I'm learning, so explain each part simply.
intermediate For scroll-based animations, lazy loading, or resize layouts
My [app] has a form (or text editor) where I want to auto-save the user's work as they type, but without flooding the server with save requests on every keystroke. Set up a debounced auto-save that: - Saves automatically [1 second / 2 seconds] after the user stops editing - Shows a "Saving..." indicator while the save is in progress - Shows "Saved ✓" when the server confirms - If the user keeps typing, resets the timer (doesn't save mid-sentence) - Handles save failures with a retry and a visible warning - Saves immediately when the user navigates away (don't lose work) My stack: [your framework and language here] I'm learning, so explain each part simply.
advanced For editors, note apps, or any form with auto-save

Common Debouncing & Throttling Mistakes to Avoid

Using throttle when you need debounce (or vice versa)

They solve different problems. Debounce waits for a pause in activity ("fire after silence"). Throttle limits frequency ("fire at most once per interval"). A search box needs debounce. A scroll handler needs throttle. Mixing them up gives you either delayed responses or still too many calls.

Setting the delay too high

A 2-second debounce on a search box makes users think the app is broken. Start with 300ms for typing inputs, 100-200ms for scroll/resize. Test it yourself: if it feels sluggish, lower the delay.

Forgetting to cancel pending work

If a user types "cat", waits, then types "dog", you might get results for "cat" arriving after "dog" results, overwriting the correct answer. Always cancel the previous API call when a new one starts. Tell your AI: "cancel the previous request when a new one fires."

Debouncing a button the user expects to work instantly

Never debounce "Submit", "Buy", or "Delete" buttons. Users click once and expect immediate action. If you're worried about double-clicks, disable the button after the first click instead. Debounce is for continuous input, not deliberate actions.

Related Building Blocks

COURSE

Ready to Build Real Products?

Learn to ship MicroSaaS apps with AI in the Solo Builder course.

Start Building →