What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
The Node.js event loop coordinates when JavaScript callbacks for timers, I/O, and other asynchronous work can run. It does not run JavaScript callbacks simultaneously: each callback runs to completion on the event-loop thread, so a slow callback delays other ready work.
What the Node.js event loop does
Node.js first runs the current JavaScript operation. That code can register an event handler, schedule a timer, or start an asynchronous operation such as file or network I/O. When the current operation finishes, the event loop processes callbacks that are ready to run.
As an Amazon Associate I earn from qualifying purchases.
While JavaScript is running, the operating system can handle many I/O operations in the background. Some tasks that lack a suitable non-blocking operating-system facility, as well as selected expensive tasks, can use libuv’s worker pool. When the work completes, its JavaScript callback still runs on the event-loop thread.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Think of one checkout clerk handling a queue: the system can make progress while waiting for an outside response, but once the clerk starts a task, it must finish before the next task is handled. The analogy is limited because Node.js delegates some work to the operating system and worker pool, and its event loop has distinct phases.
#1 Best Overall
Which phases matter for common callbacks?
The phases below are a simplified model for understanding callback order. Node.js notes that platform implementations differ in some details.
- Timers: callbacks for
setTimeout()andsetInterval()become eligible after their time thresholds. - Pending callbacks: certain deferred system callbacks are handled here.
- Poll: Node.js retrieves and processes most I/O events. It may wait here when no work is ready.
- Check: callbacks scheduled with
setImmediate()run here, after poll callbacks. - Close callbacks: some close events, such as an abrupt socket closure, are delivered here.
Idle and prepare are internal steps that beginner explanations can usually omit. Phases describe how Node.js organizes work; they do not mean every asynchronous operation runs in a worker thread.
Rank #2
Why a timer is not an exact deadline
A timeout specifies when a callback may become eligible, not the exact time it will run. As the Node.js event-loop guide puts it: “A timer specifies the threshold after which a provided callback may be executed rather than the exact time a person wants it to be executed.”
For example, if code schedules a 100 ms timeout and JavaScript is busy when that threshold passes, the callback must wait until the event loop can run it. A callback that takes 10 ms after an I/O completion can also push a nominal 100 ms timer later than 100 ms from scheduling. Use timers for “not before this threshold,” not as a clock guaranteeing an exact execution time.
Rank #3
How the scheduling APIs differ
These APIs differ in when their callbacks become eligible and how they relate to the current operation and I/O. Their ordering should not be inferred from a millisecond value alone.
| API | When its callback is eligible | Ordering guidance | Current documentation status |
|---|---|---|---|
setTimeout(fn, delay) |
After the timer threshold has passed. | Not an exact deadline; other JavaScript work and scheduling can delay it. | Timer API. |
setImmediate(fn) |
In the check phase, after I/O callbacks. | From an I/O callback, the documented example runs the immediate first. From the main module, order against a zero-delay timeout can vary. | Immediate API details are documented in the current Node.js v26.10.0 timers documentation. |
process.nextTick(fn) |
After the current JavaScript operation completes, before the event loop continues. | Recursive scheduling can prevent the loop from reaching poll and starve I/O. | Marked Legacy in the current Node.js v26.10.0 process documentation; Node.js recommends queueMicrotask() for most uses. |
queueMicrotask(fn) |
As a microtask after the current JavaScript operation. | Use it for most cases where older code might use process.nextTick(); do not treat either as a timer or I/O callback. |
Recommended by the current process documentation for most uses instead of process.nextTick(). |
Example: scheduling from the main module
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
Do not rely on one universal order for this example. When both are scheduled from the main module, either may appear first because timing and process conditions affect which callback becomes eligible first.
Rank #4
Example: scheduling from an I/O callback
const fs = require('node:fs');
fs.readFile(__filename, () => {
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
});
In the documented I/O-callback example, setImmediate() runs first: it is handled in the check phase after poll callbacks. That context-specific result is not a universal rule for calls made elsewhere.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Example: next tick before the loop continues
console.log('start');
process.nextTick(() => console.log('next tick'));
console.log('end');
The synchronous output is start, then end; the next-tick callback runs after the current JavaScript operation completes and before the event loop continues. Avoid recursively scheduling next-tick callbacks, because doing so can keep the loop from processing I/O.
What changed in Node.js 20
The Node.js guide notes a timer behavior change beginning with Node.js 20, which uses libuv 1.45.0: timers began running after poll in each iteration, whereas earlier versions ran them before poll. This can affect interactions between timers and immediates. When reasoning about subtle ordering, account for the Node.js version and the context in which callbacks were scheduled rather than assuming a single ordering rule across versions.
Why CPU-heavy JavaScript blocks Node.js
Node.js can serve many clients with a small number of threads, but a long JavaScript callback occupies the event-loop thread until it finishes. During that time, the thread cannot service other ready callbacks. This can reduce throughput and can create a security risk if crafted input triggers expensive synchronous computation.
Keep callbacks small. For genuinely CPU-intensive work, use an appropriate worker strategy rather than expecting asynchronous I/O to make the computation non-blocking. The Node.js guidance on not blocking the event loop or worker pool explains the distinction: operating-system I/O and tasks performed by libuv’s worker pool are not the same as JavaScript running on the event-loop thread.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




