Course contentsShow
← Node.js
Lesson 471 of 1,9805. Streams and BackpressureFree lesson

Non-Blocking I/O Scheduling

Coordinate stream processing with OS-level I/O scheduling to optimize disk or network access.

In this lesson, you will learn how to orchestrate your stream processing to align with the OS-level I/O scheduler, ensuring your Node.js application doesn't overwhelm the underlying disk or network hardware.

The Bottleneck Problem

When you stream large volumes of data—like pushing logs to a high-speed NVMe drive or reading multiple files simultaneously—you might inadvertently create a "request storm." Even though Node.js is non-blocking, if your code attempts to push data faster than the OS can physically write it to the disk controller or transmit it over a NIC (Network Interface Card), the OS kernel places your requests into a queue. If this queue grows too large, you suffer from high latency and context-switching overhead.

Aligning Streams with I/O Scheduling

To optimize this, you must treat your stream’s highWaterMark as a communication tool with the OS scheduler. Instead of dumping data as fast as the Event Loop can process it, you tune your stream’s buffer size to match the block size of the underlying storage or the MTU (Maximum Transmission Unit) of your network interface.

Consider a file-writer stream. If you know your disk's optimal block size is 64KB, setting a highWaterMark that is a multiple of this value prevents the OS from having to perform "read-modify-write" cycles or partial block writes, which are costly at the hardware level:

const fs = require('fs');

// We align the highWaterMark (64KB) to match 
// common disk block sizes, reducing OS-level I/O overhead.
const writeStream = fs.createWriteStream('large-data.bin', {
  highWaterMark: 64 * 1024 
});

// By respecting backpressure, we ensure we only request
// more data from the source when the OS scheduler has
// successfully cleared the current block from the queue.
sourceStream.pipe(writeStream);

By allowing your stream’s backpressure mechanism to signal when the buffer is empty, you are essentially waiting for the OS I/O scheduler to signal that the physical hardware is ready for the next operation. This prevents the "clogging" of the OS request queue, ensuring your I/O operations happen in smooth, predictable bursts rather than chaotic, overlapping spikes.

Key Takeaway: Align your stream’s highWaterMark with hardware-level block sizes and respect backpressure to keep the OS I/O scheduler running at peak efficiency.