How to Clear All Timeouts in JavaScript (clearAllTimeout Explained)

Muhaymin Bin Mehmood

Muhaymin Bin Mehmood

·
7 min read
Published Dec 5, 2024
Updated Oct 9, 2026
What is clearAllTimeout() and How to use it in JavaScript: A Complete Guide Banner Image
11 min read
1,057 words
16 sections9 code blocks

JavaScript has no built-in clearAllTimeout(). To cancel several timeouts at once, keep their IDs and call clearTimeout() on each one. This guide gives you a small timer group that does that for you, shows the browser-only trick that clears every timer on a page (and why it's risky), and covers intervals, React, debouncing and Node.js.

Tested with: Chromium 156 and WebKit 27.2 (Safari's engine) via Playwright, Node.js 20.20 and React 19.3, October 2026.

clearTimeout Basics

setTimeout() returns an ID. Pass that ID to clearTimeout() to cancel the callback before it runs:

JavaScript
const timeoutId = setTimeout(() => {
  console.log("This never runs");
}, 2000);

clearTimeout(timeoutId); // cancel it before the 2 seconds are up
  • Browsers return a number (typeof id === "number"); Node.js returns a Timeout object. Treat the ID as opaque and just pass it back.
  • Clearing is always safe: clearTimeout(undefined), an ID that already ran, or any other bad value does nothing and doesn't throw. In our tests none of them threw.
  • clearTimeout and clearInterval share the same IDs. In our tests clearTimeout() stopped an interval and clearInterval() cancelled a timeout, in Chromium, WebKit and Node.js. Use the matching one anyway, so the code says what it means.

See MDN for setTimeout and clearTimeout.

How to Clear All Your Timeouts at Once

Wrap setTimeout and setInterval so every ID goes into a Set, and remove each timeout's ID once it has run:

JavaScript
// A group of timers you can cancel together. Works in browsers and Node.js.
export function createTimerGroup() {
  const timeouts = new Set();
  const intervals = new Set();

  return {
    setTimeout(callback, delay, ...args) {
      const id = setTimeout(() => {
        timeouts.delete(id); // forget it once it has run
        callback(...args);
      }, delay);
      timeouts.add(id);
      return id;
    },

    setInterval(callback, delay, ...args) {
      const id = setInterval(callback, delay, ...args);
      intervals.add(id);
      return id;
    },

    clear(id) {
      clearTimeout(id);
      clearInterval(id);
      timeouts.delete(id);
      intervals.delete(id);
    },

    clearAll() {
      timeouts.forEach((id) => clearTimeout(id));
      intervals.forEach((id) => clearInterval(id));
      timeouts.clear();
      intervals.clear();
    },

    get size() {
      return timeouts.size + intervals.size;
    },
  };
}
JavaScript
import { createTimerGroup } from "./timer-group.js";

const timers = createTimerGroup();

timers.setTimeout(() => showHint("Need help?"), 5000);
timers.setTimeout(() => autosave(), 30000);
timers.setInterval(() => refreshClock(), 1000);

// Later, e.g. when the user leaves the page or closes a dialog:
timers.clearAll();
console.log(timers.size); // 0
  • A Set, not an array: deleting a finished ID is instant, and the same ID can't be stored twice.
  • Finished timeouts are forgotten. Many examples push IDs into an array and never remove them. In our test, an array like that still held 5 IDs after all 5 timeouts had run; the group's size was 0.
  • One group per feature: a dialog, a game level or a component can each have its own group, so clearing one doesn't touch the others.

In our tests, clearAll() stopped five pending timeouts and an interval before any of them ran, and clear(id) cancelled just one timeout while the other still ran.

Why not a global array?

JavaScript
let timeoutIds = [];
for (let i = 0; i < 5; i++) {
  timeoutIds.push(setTimeout(() => {}, 1000));
}
// After all five have run, timeoutIds.length is still 5.
// In a long-running page this array only ever grows.

A global let timeoutIds also breaks easily: an earlier version of this article declared it in two snippets, and running both together throws SyntaxError: Identifier 'timeoutIds' has already been declared. A group created with a function avoids both problems.

Clearing Every Timer on the Page (Browser Only)

If you need to stop timers you didn't create yourself, for example while debugging or in a test, there's a well-known loop:

JavaScript
// Browser only: cancels EVERY pending timeout and interval on the page,
// including ones created by libraries, analytics and ads. Use with care.
export function clearEveryTimer() {
  // Browsers hand out timer IDs as increasing numbers, so a new timer's ID
  // is higher than every pending one.
  const highestId = setTimeout(() => {}, 0);
  for (let id = highestId; id > 0; id--) {
    clearTimeout(id);
  }
}

It relies on browsers giving out timer IDs as increasing numbers, so it clears every ID from the newest one down to 1. In Chromium and WebKit it stopped two timeouts and an interval that it had no reference to. But be careful:

  • It cancels everyone's timers, including your framework's, analytics and ads. While testing this article, it also cancelled the timers our own React test was waiting on, so that test never finished.
  • It doesn't work in Node.js, where IDs are objects, not numbers. In our Node.js test, every callback still ran.

Use it for debugging, tests or a bookmarklet, not in production code. For your own timers, use a timer group.

Clearing Timeouts in React

A timeout that runs after a component unmounts can update state that no longer exists, or close something twice. This hook gives each component its own group and clears it on unmount:

JSX
// useTimeouts.jsx
import { useEffect, useRef } from "react";
import { createTimerGroup } from "./timer-group";

// One timer group per component; everything is cleared on unmount.
export function useTimeouts() {
  const groupRef = useRef(null);
  if (!groupRef.current) groupRef.current = createTimerGroup();

  useEffect(() => {
    const group = groupRef.current;
    return () => group.clearAll();
  }, []);

  return groupRef.current;
}

// Usage
export function Toast({ message, onClose }) {
  const timers = useTimeouts();

  useEffect(() => {
    timers.setTimeout(onClose, 3000); // auto-close after 3 s
  }, [timers, onClose]);

  return (
    <div role="status">
      {message}
      <button onClick={() => { timers.clearAll(); onClose(); }}>Close</button>
    </div>
  );
}
  • The group is created once per component (useRef) and cleared in the effect's cleanup.
  • In our React 19.3 test under StrictMode (which mounts, unmounts and remounts effects in development), a timeout set in an effect still ran once while mounted and never ran after unmount. The Toast's Close button cleared its auto-close timer.
  • Pass a stable onClose (for example wrapped in useCallback); a new function on every render re-runs the effect and schedules another timeout.

For a single timeout, a plain cleanup is enough: useEffect(() => { const id = setTimeout(fn, 1000); return () => clearTimeout(id); }, []). If you see effects running twice in development, read our guide to useEffect running twice.

Debounce: Cancel the Previous Timeout

Often you don't want to clear all timeouts, only the previous one, so an action runs once after the user stops typing or clicking:

JavaScript
// Run `fn` only after calls have stopped for `delay` ms.
export function debounce(fn, delay) {
  let timeoutId;

  function debounced(...args) {
    clearTimeout(timeoutId); // cancel the previous pending call
    timeoutId = setTimeout(() => fn.apply(this, args), delay);
  }

  debounced.cancel = () => clearTimeout(timeoutId);
  return debounced;
}

// Example: save a draft 500 ms after the user stops typing
const saveDraft = debounce((text) => console.log("Saving:", text), 500);
textarea.addEventListener("input", (e) => saveDraft(e.target.value));

In our test, four quick calls produced a single run with the last value, and cancel() stopped a pending call. This is the pattern behind search-as-you-type; see it in our dynamic search bar guide.

setTimeout vs setInterval

setTimeoutsetInterval
RunsOnce, after the delayRepeatedly, every delay
Cancel withclearTimeout(id)clearInterval(id)
Good forDelays, debouncing, polling after each requestClocks, simple animations, fixed ticks
Watch out forForgetting to cancel on unmountSlow callbacks overlapping; runs forever until cleared
JavaScript
const intervalId = setInterval(tick, 1000);
clearInterval(intervalId);

// Repeating async work: schedule the next run only after this one finishes,
// so slow requests never overlap.
let pollId;
let polling = true;

async function poll() {
  await refreshData();
  if (polling) pollId = setTimeout(poll, 5000);
}
poll();

function stopPolling() {
  polling = false;      // a request in flight won't schedule another run
  clearTimeout(pollId); // and a scheduled run is cancelled
}

The polling flag matters: in our test, calling only clearTimeout(pollId) while a request was still running didn't stop the loop, because the request finished afterwards and scheduled a new timeout. Browsers also slow down timers in background tabs; see our guide to detecting tab changes if you want to pause work when the page is hidden.

Cancelling Timers in Node.js

Node.js has a promise-based setTimeout that accepts an AbortSignal, so one abort() cancels every timer that shares the signal:

JavaScript
import { setTimeout as sleep } from "node:timers/promises";

const controller = new AbortController();

sleep(5000, "done", { signal: controller.signal })
  .then((value) => console.log(value))
  .catch((err) => {
    if (err.name === "AbortError") console.log("Timer cancelled");
    else throw err;
  });

controller.abort(); // cancels every timer that uses this signal

In our test this printed "Timer cancelled" and the script exited in about 130 ms instead of waiting 5 seconds. With the classic API, clearTimeout(timeout) works as in the browser, and timeout.unref() lets the process exit even if the timer is still pending. See the Node.js timers docs.

Common Mistakes

MistakeWhat happensFix
Not saving the ID from setTimeoutYou can't cancel it laterconst id = setTimeout(…)
Pushing IDs into an array and never removing themThe array grows foreverUse a Set and delete IDs when they run
No cleanup in React effectsCallbacks run after unmountReturn () => clearTimeout(id)
Using the clear-every-timer loop in productionBreaks libraries, ads and frameworksTrack and clear only your own timers
setInterval for slow async workRequests overlap and pile upSchedule the next setTimeout after each run
Passing a string: setTimeout("fn()", 100)Runs eval-like code; blocked by strict CSPPass a function

FAQs

Is there a clearAllTimeout() function in JavaScript?

No. Neither browsers nor Node.js have one. Keep your timer IDs (the timer group above does it for you) and clear them in a loop.

How do I clear all timeouts in JavaScript?

For your own timers, store the IDs and call clearTimeout() on each, or use createTimerGroup().clearAll(). To clear every timer on a page, including other scripts', loop from a new timer's ID down to 1 calling clearTimeout, but only for debugging.

Does clearTimeout work on setInterval?

Yes. Timeouts and intervals share one pool of IDs, so clearTimeout() stops an interval and clearInterval() cancels a timeout. Using the matching function is clearer.

What does setTimeout return?

A positive integer in browsers and a Timeout object in Node.js. Either way, it's the value you pass to clearTimeout.

What happens if I call clearTimeout after the timeout has run?

Nothing. It's safe to call, which is why cleanup functions can always clear without checking first.

How do I clear a timeout in React?

Return a cleanup function from useEffect that calls clearTimeout(id), or use the useTimeouts hook above for several timers.

No comments yet. Be the first to comment!

Leave a Comment

2000 characters remaining

Related Articles

View all
Muhaymin Bin Mehmood

About Muhaymin Bin Mehmood

Front-end Developer skilled in the MERN stack, experienced in web and mobile development. Proficient in React.js, Node.js, and Express.js, with a focus on client interactions, sales support, and high-performance applications.