The Event Loop and Non-Blocking I/O

Site Admin · 11 Sep 2026 · 9 views

The Event Loop and Non-Blocking I/O

Node uses a single main thread with an event loop underneath. Understanding this model explains why Node handles many connections with little memory.

Blocking vs. non-blocking

A blocking operation like reading a file synchronously stops every other request while it finishes. Non-blocking versions start the work and continue, running a callback when done:

// Blocking
const data = fs.readFileSync('file.txt', 'utf8');
console.log(data);

// Non-blocking
fs.readFile('file.txt', 'utf8', (err, data) => {
  console.log(data);
});

How the event loop works

The event loop is a cycle that watches several queues. It runs timers, then pending I/O callbacks, then setImmediate callbacks, then closes, repeating forever while the process lives. When an operation finishes, its callback is queued and picked up in a later tick.

What that means for your code

Long synchronous work starves the loop, so a heavy loop in one request blocks everything else. Offload with async APIs, worker threads, or child processes. Prefer the callback and promise versions of fs and network functions.

Promises fit the loop

await lets you write async code that reads like sync code while staying non-blocking:

async function load() {
  const data = await fs.promises.readFile('file.txt', 'utf8');
  console.log(data);
}

The event loop keeps accepting new work while file reads run in the background thread pool.

Key Points

  • Node runs JavaScript on a single main thread.
  • Non-blocking I/O keeps the server responsive.
  • The event loop cycles through callback queues.
  • Sync versions of file and network calls block others.
  • Use async, await, and promises for clean non-blocking code.
Share this post:

Comments (0)

Please login or register to comment.