Debounce

FrontendTier 2 · build and shipPhase 2 · Make it a store

Waiting for a short pause in typing before acting, instead of reacting to every single keystroke.

Some actions fire far more often than they need to: a search box that queries on every keystroke sends a request for k, ka, kac, most of them instantly stale. That floods the backend and wastes work. Debounce exists to wait for a short pause before acting, so a burst of rapid events collapses into the one request that actually matters.

If search fired on every letter, typing "biryani" would send seven requests, six of them wasted. Debounce waits until you stop typing for a moment, say 300ms, then sends one request.

It is a small frontend technique with a big effect: it keeps the experience feeling responsive while sparing the server a flood of pointless work.

Type 'kacchi biryani' and predict how many requests each side sends.
Without debounce
0 requests
With debounce (320 ms)
0 requests
No requests yet. Start typing above.
Debounce collapses a burst of keystrokes into one request: it waits for a pause, then fires.
A junior PM, stuck

The backend dev pinged me saying our search traffic is about six times what our user numbers suggest, and asked whether the frontend debounces. I nodded and said I would check, but I do not actually know whether it does or what debouncing would change. I need to give him a real answer, not a shrug.

The dev is pointing at a real number, and you can settle it by looking at what one person's typing actually sends. Every letter typed in the search box can fire its own request; debouncing just means waiting for a short pause before firing. I pulled the search requests one customer generated typing kacchi at Friday lunch, first exactly as the app ships today, then how the same typing would behave with a 300ms debounce. The six-to-one is right there in the timestamps.

The search requests from one customer typing kacchi, Friday 12:41
01As shipped today, no debounce
fires
12:41:03.102 GET /api/search?q=k
12:41:03.240 GET /api/search?q=ka
12:41:03.390 GET /api/search?q=kac
12:41:03.560 GET /api/search?q=kacc
12:41:03.720 GET /api/search?q=kacch
12:41:03.910 GET /api/search?q=kacchi
02The same typing with a 300ms debounce
fires
12:41:03.102 to 12:41:03.910 typing, no request sent yet
12:41:04.210 GET /api/search?q=kacchi

Click a step to see the lines it points at.

Reading 6x traffic as a capacity problem and asking for more servers. The load is self-inflicted by per-keystroke requests, so debounce removes it for free, while scaling up just pays to serve throwaway queries faster.
Setting the debounce so long the box feels dead. Too long a pause and autocomplete lags behind the user; the timing is a genuine trade, which is why it is a number you can tune rather than a switch.
Assuming the five partial requests are harmless because each returns fast. Every one still opens a connection, runs a query, and counts against rate limits, and at peak that wasted five-sixths is exactly what tips the backend over.
Trying to fix it on the server. By the time a request reaches the backend it has already crossed the network; the only place to stop these being sent is the frontend, before the trip.

Reply to the dev: "Checked the recorded requests. As shipped, search fires one request per keystroke, so typing kacchi sends six, which is the six-to-one you are seeing. Can we add a 300ms debounce so it sends once after the user pauses." You read a request feed and told self-inflicted load apart from real demand, then scoped the fix to the right side of the network. That is the skill.

It is the answer to "why does search wait a beat before responding?" A deliberate trade between feeling instant and overloading the backend.
If autocomplete feels laggy or too eager, the debounce timing is a knob you can ask to adjust.

"Autocomplete feels sluggish, let's drop the debounce from 400 to 250ms."

Appears in Phase 2, Make it a store.