Study notes · 10% of the exam

Streams, Buffers and Backpressure

Know how Buffers share memory and encode text, how streams buffer and apply backpressure, and why `pipeline` beats chained `.pipe()` calls in production.

Key points

  1. 1

    Buffer.alloc zero-fills; Buffer.allocUnsafe is faster but may contain old memory. subarray and Buffer.from(arrayBuffer) share memory, while Buffer.from(buffer | typedArray) copies.

  2. 2

    String length is UTF-16 code units; Buffer.byteLength is encoded bytes. Decode chunked text with setEncoding or StringDecoder so multi-byte characters split across chunks survive.

  3. 3

    write() always queues the chunk and returns false once the buffer reaches highWaterMark. Stop producing and wait for drain, or let pipeline do it for you.

  4. 4

    pipeline(a, b, c, cb) forwards errors, destroys every stream on failure or premature close, and calls back once. .pipe() handles backpressure but not errors or cleanup.

  5. 5

    Async iteration (for await) is pull-based and respects backpressure. Breaking out of the loop destroys the stream. Async generators can act as transforms inside pipeline.

  6. 6

    A Transform must call its callback exactly once per chunk. Trailing output belongs in flush, and a missing callback stalls the whole pipeline without an error.

  7. 7

    Readables start paused and keep data until someone reads it. A readable listener takes precedence over data. fetch bodies are web streams; bridge them with Readable.fromWeb.

Common traps

  • Buffer#slice shares memory, unlike Array and TypedArray slice, which copy.

  • An unhandled error event on any piped stream (for example gunzip on bad input) crashes the whole process.

  • Readable.from('abc') emits the whole string as one chunk; it does not iterate characters.

Test yourself on Streams, Buffers and Backpressure

Ten questions, with the answer and explanation after each one.