How to Understand the Event Loop in JavaScript
A step-by-step guide on how the JavaScript Event Loop coordinates the Call Stack, Web APIs, the Callback Queue, and the Microtask Queue.
Understand the Problem the Event Loop Solves
JavaScript runs on a single thread, meaning it can only do one thing at a time. But browsers and Node.js need to handle timers, network requests, and user events without freezing the main thread. The Event Loop is the mechanism that coordinates asynchronous operations by offloading work to external APIs and scheduling callbacks to run on the main thread when the stack is empty.
Understand the Role of Web APIs
When you call setTimeout, fetch, or addEventListener, the browser provides these functionalities through Web APIs that run outside the JavaScript engine in separate threads managed by the browser. JavaScript hands off the task, including the callback, to the Web API and immediately continues executing the next line. The Web API operates in the background without blocking the Call Stack.
Understand the Callback Queue
When a Web API finishes its work, such as a timer expiring or a fetch response arriving, it does not execute the callback immediately. Instead, it places the callback into the Callback Queue, also called the Task Queue or Macrotask Queue. Callbacks in this queue wait patiently until the Event Loop is ready to process them.
Understand How the Event Loop Works
The Event Loop continuously monitors two things: the Call Stack and the Callback Queue. Its single job is to check if the Call Stack is empty. If the Call Stack has any frames in it, the Event Loop does nothing and waits. Only when the Call Stack is completely empty does the Event Loop take the first callback from the Callback Queue and push it onto the Call Stack for execution.
Understand the Microtask Queue
Promise callbacks attached with then, catch, and finally, as well as queueMicrotask callbacks, go into the Microtask Queue rather than the Callback Queue. The Microtask Queue has higher priority than the Callback Queue. After each task from the Callback Queue finishes and before the next one is picked up, the Event Loop completely drains the entire Microtask Queue first.
Understand the Execution Order with a Mental Model
To predict execution order, follow this sequence. First, synchronous code runs and clears the Call Stack. Second, all microtasks in the Microtask Queue run until it is empty. Third, the Event Loop picks one callback from the Callback Queue and runs it. Fourth, after that callback finishes, all new microtasks are drained again. This cycle repeats continuously for the lifetime of the program.
Understand Why setTimeout Zero Is Not Instant
Calling setTimeout with a delay of zero does not execute the callback immediately. The callback is sent to the Web API, which immediately places it in the Callback Queue after zero milliseconds. But it still must wait for the Call Stack to empty and for all pending microtasks to drain before the Event Loop picks it up. Any synchronous code and any existing Promise callbacks will run before the setTimeout zero callback.
Apply Event Loop Knowledge to Debug Async Code
Understanding the Event Loop helps you predict and debug the order in which asynchronous code executes. When you see unexpected ordering in console logs, trace through the execution mentally: identify what is synchronous, what goes to the Microtask Queue as a Promise callback, and what goes to the Callback Queue as a setTimeout or event handler. This mental model explains every async ordering puzzle you will encounter in JavaScript.
Ready to master this completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

