In this lesson, you’ll learn how to significantly boost disk I/O performance by grouping many small write operations into a single, larger chunk.
Why Batching Matters
Every time you perform a write operation to the disk, the operating system performs several expensive tasks: it translates your request, manages file system metadata, and interacts with the physical storage hardware. If you write one byte at a time, your code spends more time waiting for the "handshake" between the CPU and the disk than actually moving data.
By implementing asynchronous batching, we buffer data in memory and only trigger a system write once a specific size threshold (a "chunk") is reached or a timer expires.
The Implementation Strategy
Instead of writing immediately, you append incoming data into a Buffer or a queue. Once that buffer hits a pre-defined size (e.g., 64KB), you perform one single fs.write() operation.
Here is how you might visualize this logic:
let writeBuffer = Buffer.alloc(0);
const BATCH_SIZE = 65536; // 64KB
function processIncomingData(chunk) {
// Combine existing buffer with new data
writeBuffer = Buffer.concat([writeBuffer, chunk]);
// If we have enough data, perform a single bulk write
if (writeBuffer.length >= BATCH_SIZE) {
const dataToWrite = writeBuffer;
writeBuffer = Buffer.alloc(0); // Reset buffer
fs.write(fd, dataToWrite, (err) => {
if (err) console.error("Write failed");
});
}
}
Balancing Throughput and Latency
There is a trade-off here. While waiting to fill a 64KB buffer maximizes throughput, it increases the latency of individual write operations. If your application requires data to be flushed even if the buffer isn't full, you should implement a setTimeout to ensure that data waiting in the buffer is eventually written to disk after a set duration, even if the "batch" isn't technically complete yet.
This pattern is fundamental for high-performance systems like logging agents or database engines, where disk head movement or system call overhead can become the primary bottleneck.
Key Takeaway: Instead of hammering the disk with frequent small writes, aggregate data in memory and perform bulk writes to drastically reduce system call overhead and improve I/O throughput.