1. Introduction
setTimeout and setInterval are the classic timer functions for scheduling code to run later. setTimeout runs a function once after a minimum delay; setInterval repeats a function every fixed interval until it is explicitly stopped. Both are macrotask-based APIs: their callbacks are queued and only run once the call stack is empty and the microtask queue has been drained, so the delay you specify is a MINIMUM wait, never a guarantee.
Cricket analogy: setTimeout is like scheduling the drinks-break announcement for 30 minutes in — it only actually happens once the current over (the call stack) finishes, so it's a minimum wait, not a promise; setInterval is like the every-6-ball over change repeating until stumps, delayed if a review (microtask) is still being checked.
2. Syntax
// Run once, after at least 1000ms
const timeoutId = setTimeout(() => {
console.log("Runs once");
}, 1000);
clearTimeout(timeoutId); // cancel before it fires
// Run repeatedly, roughly every 1000ms, until cleared
const intervalId = setInterval(() => {
console.log("Runs repeatedly");
}, 1000);
clearInterval(intervalId); // MUST be called to stop it
// Passing extra arguments
setTimeout((name) => console.log("Hi", name), 500, "Alice");3. Explanation
The delay passed to setTimeout/setInterval is not a precise scheduling guarantee -- it is the minimum amount of time before the callback is eligible to run. If the call stack is busy (running other synchronous code, or many other queued tasks), the callback waits until the stack is free, so the actual delay is often longer than requested. This effect compounds with setInterval: because each 'tick' is scheduled independently and can be delayed by whatever else is running, long-running callbacks or a busy main thread can cause 'drift', where intervals fire later and later relative to their originally intended schedule, and in some environments consecutive intervals can even be skipped.
Cricket analogy: Announcing "drinks in 2 minutes" doesn't mean exactly 2 minutes if a DRS review is dragging on — the actual break comes later; and if every over's mid-innings update is scheduled at fixed intervals, a string of long reviews compounds into serious drift, with some scheduled updates skipped entirely.
Unlike setTimeout, which fires once and is naturally 'done', setInterval keeps scheduling itself forever until you explicitly call clearInterval() with the ID it returned. Forgetting to clear an interval -- for example, one started when a UI component mounts but never cleared when it unmounts -- is a classic source of memory leaks and 'zombie' callbacks that keep running (and consuming resources, or throwing errors against stale data) long after they're needed.
4. Example
console.log("Start");
let count = 0;
const intervalId = setInterval(() => {
count++;
console.log("Tick", count);
if (count === 3) {
clearInterval(intervalId);
console.log("Interval cleared");
}
}, 100);
setTimeout(() => {
console.log("Timeout fired once");
}, 250);
console.log("End");5. Output
Start
End
Tick 1
Tick 2
Timeout fired once
Tick 3
Interval cleared6. Key Takeaways
- setTimeout schedules a callback once after a MINIMUM delay; setInterval repeats it every interval until cleared.
- Both are macrotasks: their callbacks run only after the call stack is empty and the microtask queue is drained.
- The requested delay is never a hard guarantee -- a busy main thread delays timer callbacks further.
- setInterval can drift over time as each tick's actual timing depends on whatever else is running.
- Always store the ID returned by setInterval and call clearInterval() when it's no longer needed, to avoid leaks.
- Extra arguments can be passed to the callback as additional parameters after the delay.
Practice what you learned
1. What does the delay argument passed to setTimeout actually guarantee?
2. What must you do to stop a setInterval from continuing to fire?
3. What is 'timer drift' in the context of setInterval?
4. In the example, an interval ticks every 100ms and a setTimeout is scheduled for 250ms. In what order do 'Tick 2' and 'Timeout fired once' occur?
5. Why is forgetting to call clearInterval() considered a common bug?
Was this page helpful?
You May Also Like
The Event Loop in JavaScript
Understand the call stack, macrotask queue, and microtask queue, and master the ordering rules that govern async execution.
Callbacks and Asynchronous JavaScript
Learn how JavaScript handles operations that take time using callback functions, and why deeply nested callbacks lead to callback hell.
Promises in JavaScript
Understand the Promise object, its three states, and how .then/.catch/.finally chaining replaces nested callbacks.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics