Course contentsShow
← Node.js
Lesson 62 of 1,9801. Node.js Foundations and Runtime InternalsFree lesson

Handling Binary Data streams

Process raw binary streams efficiently to reduce memory overhead.

In this lesson, you will learn how to process raw binary data streams in Node.js to keep your memory usage low and stable.

When dealing with large files—like images, videos, or raw network packets—trying to load the entire file into memory at once is a recipe for a crash. If your file is 2GB and your server only has 1GB of RAM available for the process, your application will trigger an out-of-memory error.

Processing via Buffers

Instead of loading the whole file, we use Streams to process data in small, manageable chunks. These chunks are represented as Buffer objects, which are essentially raw memory allocations outside of the V8 heap. By processing these chunks one at a time, we ensure that only a few kilobytes of data exist in memory at any single moment, regardless of the total file size.

Here is how you handle a raw binary stream using modern async iteration:

const fs = require('fs');

async function processBinaryFile(filePath) {
  // Create a readable stream for the file
  const fileStream = fs.createReadStream(filePath);

  // Use async iteration to process the stream
  for await (const chunk of fileStream) {
    // 'chunk' is a Buffer containing a small slice of the binary data
    console.log(`Processing ${chunk.length} bytes...`);
    
    // You can perform operations here, like encryption or transformation,
    // without ever loading the full file into memory.
  }
}

Why this is Efficient

When you use for await...of, Node.js internally manages the backpressure for you. If your logic inside the loop is slower than the disk reading the file, Node.js pauses the stream. This prevents the "buffer pile-up" that happens when a fast producer (the disk) outpaces a slow consumer (your logic).

By working with these binary chunks directly, you avoid the overhead of converting raw bytes into heavy JavaScript strings or objects. This minimizes the work required by the Garbage Collector and keeps your process memory footprint tiny and predictable.

Key Takeaway: By iterating over binary streams as small, discrete Buffer chunks, you maintain a constant, low memory footprint regardless of the total size of the data being processed.