<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Abdul Haseeb</title>
    <description>The latest articles on DEV Community by Abdul Haseeb (@abhaseeb2115).</description>
    <link>https://dev.to/abhaseeb2115</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3678710%2F47bb8fe7-e04f-47ee-9ebb-9297625b4cf9.jpg</url>
      <title>DEV Community: Abdul Haseeb</title>
      <link>https://dev.to/abhaseeb2115</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abhaseeb2115"/>
    <language>en</language>
    <item>
      <title>Node.js Event Loop Explained</title>
      <dc:creator>Abdul Haseeb</dc:creator>
      <pubDate>Wed, 24 Jun 2026 00:26:02 +0000</pubDate>
      <link>https://dev.to/abhaseeb2115/nodejs-event-loop-explained-4441</link>
      <guid>https://dev.to/abhaseeb2115/nodejs-event-loop-explained-4441</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjxzldl3sy6sib9fwoqnc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjxzldl3sy6sib9fwoqnc.png" alt="Node.js Event Loop CheatSheet" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Node.js Event Loop: Microtasks, Macrotasks, and Async Execution
&lt;/h2&gt;

&lt;p&gt;Many Node.js bugs become much easier to understand once you know where a callback actually gets queued.&lt;/p&gt;

&lt;p&gt;Why does &lt;code&gt;process.nextTick&lt;/code&gt; run before a resolved Promise? Why does &lt;code&gt;setImmediate&lt;/code&gt; sometimes run before &lt;code&gt;setTimeout&lt;/code&gt;? Why can a single synchronous function freeze an entire server?&lt;/p&gt;

&lt;p&gt;The answer is the event loop.&lt;/p&gt;

&lt;p&gt;This article explains how the Node.js event loop works, the phases it runs through, and how microtasks and macrotasks interact during each iteration.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Event Loop Actually Is
&lt;/h2&gt;

&lt;p&gt;The event loop is a loop that runs continuously, checking whether there is work to do and executing it in a specific order.&lt;/p&gt;

&lt;p&gt;Node.js uses &lt;a href="https://libuv.org/" rel="noopener noreferrer"&gt;libuv&lt;/a&gt;, a C library, to handle I/O operations asynchronously using the operating system's native capabilities. When an async operation completes, its callback is queued and the event loop picks it up during the appropriate phase.&lt;/p&gt;

&lt;p&gt;The key point is that JavaScript itself runs on a single thread. The event loop does not provide parallel execution. It provides deferred execution, allowing long running operations to be handled outside the main thread while their results are processed later without blocking application code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Phases of the Event Loop
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy3u8ezsgcphx2hfi6iak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy3u8ezsgcphx2hfi6iak.png" alt="Node.js Event Loop Phases" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The event loop runs through a fixed set of phases in order. Each phase has a queue of callbacks waiting to execute.&lt;/p&gt;

&lt;p&gt;The main phases are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;timers&lt;/strong&gt;: executes callbacks scheduled by &lt;code&gt;setTimeout&lt;/code&gt; and &lt;code&gt;setInterval&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pending callbacks&lt;/strong&gt;: executes certain I/O callbacks deferred from the previous iteration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;idle, prepare&lt;/strong&gt;: internal Node.js operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;poll&lt;/strong&gt;: retrieves new I/O events and executes their callbacks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;check&lt;/strong&gt;: executes &lt;code&gt;setImmediate&lt;/code&gt; callbacks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;close callbacks&lt;/strong&gt;: handles close events such as &lt;code&gt;socket.on('close')&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The poll phase is where most I/O activity is processed. If no timers are ready and no &lt;code&gt;setImmediate&lt;/code&gt; callbacks are waiting, the event loop can remain in the poll phase while waiting for new I/O events.&lt;/p&gt;

&lt;p&gt;Once work becomes available, the loop continues through the remaining phases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microtasks vs Macrotasks
&lt;/h2&gt;

&lt;p&gt;Not all asynchronous callbacks are treated equally. There are two categories: microtasks and macrotasks.&lt;/p&gt;

&lt;p&gt;Macrotasks include &lt;code&gt;setTimeout&lt;/code&gt;, &lt;code&gt;setInterval&lt;/code&gt;, and &lt;code&gt;setImmediate&lt;/code&gt;. Microtasks include resolved Promise callbacks and &lt;code&gt;process.nextTick&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The critical difference is that microtasks are processed before the event loop continues to the next callback or phase. In Node.js, the &lt;code&gt;process.nextTick&lt;/code&gt; queue is processed before the Promise microtask queue, which gives it even higher priority.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;setTimeout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setImmediate&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;setImmediate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Promise&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nextTick&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nextTick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Output:&lt;/span&gt;
&lt;span class="c1"&gt;// nextTick&lt;/span&gt;
&lt;span class="c1"&gt;// Promise&lt;/span&gt;
&lt;span class="c1"&gt;// setTimeout OR setImmediate&lt;/span&gt;
&lt;span class="c1"&gt;// setImmediate OR setTimeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact ordering of &lt;code&gt;setTimeout&lt;/code&gt; and &lt;code&gt;setImmediate&lt;/code&gt; depends on where they are scheduled, but &lt;code&gt;process.nextTick&lt;/code&gt; and Promise callbacks will always run first.&lt;/p&gt;

&lt;h2&gt;
  
  
  How setTimeout and setImmediate Differ
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;setImmediate&lt;/code&gt; is designed to execute during the check phase of the event loop.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;setTimeout(fn, 0)&lt;/code&gt; schedules a timer that becomes eligible to run after a minimum threshold. That threshold is not a guarantee that the callback will execute immediately.&lt;/p&gt;

&lt;p&gt;When called from the main module, the order of &lt;code&gt;setTimeout(fn, 0)&lt;/code&gt; and &lt;code&gt;setImmediate&lt;/code&gt; is not guaranteed because it depends on the state of the event loop when the process starts.&lt;/p&gt;

&lt;p&gt;However, inside an I/O callback, &lt;code&gt;setImmediate&lt;/code&gt; executes before timers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;setTimeout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;setImmediate&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;setImmediate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Output:&lt;/span&gt;
&lt;span class="c1"&gt;// setImmediate&lt;/span&gt;
&lt;span class="c1"&gt;// setTimeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes &lt;code&gt;setImmediate&lt;/code&gt; a good choice when the goal is to run something immediately after the current I/O cycle completes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blocking the Event Loop
&lt;/h2&gt;

&lt;p&gt;Because JavaScript runs on a single thread, any long running synchronous operation blocks the event loop completely.&lt;/p&gt;

&lt;p&gt;While that code is executing, no timers, requests, or I/O callbacks can be processed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;heavyComputation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;heavyComputation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples of operations that commonly block the event loop include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image processing&lt;/li&gt;
&lt;li&gt;PDF generation&lt;/li&gt;
&lt;li&gt;Compression&lt;/li&gt;
&lt;li&gt;Encryption&lt;/li&gt;
&lt;li&gt;Large CSV imports&lt;/li&gt;
&lt;li&gt;Data aggregation&lt;/li&gt;
&lt;li&gt;AI inference workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more CPU intensive the work becomes, the greater the impact on request latency and application responsiveness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Worker Threads Fit
&lt;/h2&gt;

&lt;p&gt;The event loop is excellent at coordinating asynchronous I/O, but it is not designed for CPU intensive workloads.&lt;/p&gt;

&lt;p&gt;Worker Threads allow expensive computations to run in separate threads while the main thread remains available for handling requests and processing I/O events.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Worker&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;worker_threads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./heavy-task.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Task completed:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Worker Threads introduce some overhead because data must be transferred between threads.&lt;/p&gt;

&lt;p&gt;For genuinely CPU intensive tasks, that tradeoff is usually worth it because the event loop remains responsive while the computation runs elsewhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Implications for Node.js Applications
&lt;/h2&gt;

&lt;p&gt;Understanding the event loop changes how asynchronous code should be structured.&lt;/p&gt;

&lt;p&gt;A few useful guidelines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid CPU intensive work inside request handlers.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;setImmediate&lt;/code&gt; when the goal is to yield after an I/O cycle.&lt;/li&gt;
&lt;li&gt;Be careful with recursive &lt;code&gt;process.nextTick&lt;/code&gt; calls.&lt;/li&gt;
&lt;li&gt;Remember that Promise callbacks still run synchronously once scheduled.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A recursive &lt;code&gt;process.nextTick&lt;/code&gt; can completely starve the event loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;recursiveNextTick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nextTick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recursiveNextTick&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// The event loop never gets a chance to continue&lt;/span&gt;
&lt;span class="nf"&gt;recursiveNextTick&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A safer approach is to yield using &lt;code&gt;setImmediate&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;safeRecursive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setImmediate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;safeRecursive&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;safeRecursive&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the event loop to continue processing timers, requests, and I/O callbacks between iterations.&lt;/p&gt;

&lt;p&gt;The tradeoff with &lt;code&gt;setImmediate&lt;/code&gt; in recursive patterns is slightly higher overhead per iteration compared to &lt;code&gt;process.nextTick&lt;/code&gt;, but the benefit is that other callbacks get a chance to run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting a Solid Mental Model
&lt;/h2&gt;

&lt;p&gt;The event loop is not magic. It is a structured loop with well defined phases and predictable execution rules.&lt;/p&gt;

&lt;p&gt;Most bugs involving asynchronous ordering, delayed callbacks, or unexpectedly blocked applications can be traced back to a misunderstanding of where work is being scheduled.&lt;/p&gt;

&lt;p&gt;A useful next step is exploring Node.js profiling tools such as Chrome DevTools, the built in inspector, or Clinic.js. These tools make it much easier to visualize event loop activity and identify blocking operations before they become production issues.&lt;/p&gt;

&lt;p&gt;What is the most surprising thing you have learned about the Node.js event loop?&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>backend</category>
      <category>nestjs</category>
    </item>
  </channel>
</rss>
