Suggest an editImprove this articleRefine the answer for “Combining streams and buffers for performance”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)Buffers hold the raw bytes of data, while streams control how much of that data gets read or written and when, with asynchrony and backpressure built in - together they let Node.js process huge volumes of data while keeping only a small chunk in memory at a time. **Key point:** buffers live outside the V8 heap, so passing data between streams doesn't burden the garbage collector, it just passes a reference.Shown above the full answer for quick recall.Answer (EN)Image## 1. Streams and buffers are different layers of one mechanism - **Streams** are a **high-level interface** for passing data in pieces. They manage the flow of data, queues, events, backpressure, and asynchrony. - **Buffers** are a **low-level structure** that holds **the actual bytes of data**. Streams "pack" and "unpack" those bytes, but **don't hold the data themselves**. A stream ≈ a pipe A buffer ≈ the water flowing through it ## 2. How they work together When you read a large file or an HTTP request: 1. Node.js receives data from the OS as **bytes** (via `libuv`). 2. Those bytes get placed into a **Buffer**. 3. The stream (`Readable Stream`) passes those buffers on, for example, to a `Writable Stream`. ```javascript fs.createReadStream('video.mp4') .pipe(zlib.createGzip()) .pipe(fs.createWriteStream('video.mp4.gz')); ``` Here: - the read stream → gets chunks (`Buffer`) - the gzip stream → processes them (compresses) - the write stream → saves the result and all of it happens **asynchronously and in pieces**, **without loading the whole file into memory**. ## 3. Why combining them boosts performance ### 1. Minimizing memory use - A buffer holds only part of the data (for example, 64 KB). - The stream controls **how much and when** that data gets read and written. - There's no need to keep the whole file, image, or server response in memory. Result: even with 10,000 concurrent connections, Node.js uses **hundreds of megabytes**, not gigabytes. ### 2. Instant data processing Thanks to streams, data gets **processed as it arrives**: - compression can start while the rest of the data is still being read; - an HTTP response can start going out to the client while the file is still being read. This sharply cuts **latency**. ### 3. Flow control (backpressure) Streams "know" when the receiver can't keep up: - if the writable stream is overloaded, reading temporarily **pauses**; - once the writable side frees up, reading **resumes**. That way, the system: - doesn't waste extra memory, - doesn't crash from buffer overflow. ### 4. Fewer system calls and copies Working directly with buffers (instead of JS strings and objects) allows: - avoiding type conversions (`string → bytes → string`); - fewer in-memory data copies; - faster data transfer between streams (usually just a reference to the buffer gets passed). ### 5. Native OS integration - Buffers live in **unmanaged memory (outside the V8 heap)**; - Node.js passes that data directly to system calls (`read`, `write`, `send`); - This keeps garbage collection out of the picture for large binary data. Result: fewer GC pauses → steadier, higher performance. ## 4. Example: without streams vs. with streams and buffers ```javascript // Without streams const fs = require('fs'); const zlib = require('zlib'); fs.readFile('bigfile.txt', (err, data) => { const compressed = zlib.gzipSync(data); fs.writeFileSync('bigfile.txt.gz', compressed); }); ``` Downsides: - the whole file (say, 2 GB) loads into memory; - synchronous compression and writing block the event loop. ```javascript // With streams and buffers const fs = require('fs'); const zlib = require('zlib'); fs.createReadStream('bigfile.txt') .pipe(zlib.createGzip()) .pipe(fs.createWriteStream('bigfile.txt.gz')); ``` Upsides: - data is processed **gradually** (buffer by buffer); - **low memory use**; - **high speed and scalability**. ## Summary > Combining **streams** and **buffers** is what makes Node.js able > to process huge volumes of data **without overloading memory** and **without losing speed**. > > **Buffers** provide fast access to raw bytes. > **Streams** manage the movement of those bytes, asynchrony, and load balance (backpressure). > > Together, they make Node.js **one of the most efficient tools for I/O-heavy systems**: file servers, streaming, proxies, CDNs, and more.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.