Streams Best Practices
Streams keep Node services memory-stable - these rules prevent hung sockets, OOM from unbounded buffers, and silent data loss on unhandled error events.
Search across all documentation pages
Streams keep Node services memory-stable - these rules prevent hung sockets, OOM from unbounded buffers, and silent data loss on unhandled error events.
.pipe().pipe() without error handlers as a review blocker.stream/promises.pipeline instead of bare pipe chains. Automatic destroy on error.await pipeline(...) in try/catch in HTTP handlers. Map to 500 only if headers not sent.error listeners if not using pipeline. Rare exceptions for legacy code with migration ticket.req.on('aborted') or AbortSignal._flush on Transforms buffering partial frames/lines. Do not lose trailing data.write() returning false in custom loops. Pause until drain.highWaterMark with measurements, not guesses. Watch heap and p99 latency.Array of chunks before concat. Use pipeline or bounded queue.content-type and disposition headers before body bytes. Required for downloads and NDJSON.Content-Length when size known. Better CDN behavior and download progress.Readable.from async iterables for simple sources. Subclass Readable when stateful _read needed.fromWeb/toWeb at fetch boundaries. Do not buffer response.arrayBuffer() by default.Manual pipe chains often miss error propagation - production leaks sockets and file handles.
Small known-size payloads (KB scale), crypto HMAC over bounded body, in-memory transforms in tests.
Default JSON parser buffers - use raw stream or busboy for multipart streaming uploads.
Fastify supports stream responses natively - still use pipeline for multi-stage processing before reply.
@aws-sdk/lib-storage Upload with stream body - respects backpressure to S3 multipart API.
Redis protocol is request/response - usually not a Writable stream sink; use commands or dedicated client APIs.
Writable with slow async _write and producer pushing fast - assert memory stable over time.
No - opt in explicitly when streaming records/events, not bytes.
Same API - test large file streams on target deploy OS for antivirus interference.
CPU-heavy per-chunk work may belong in worker - stream coordinates flow on main thread.
Use underlying Express/Fastify adapter patterns or @nestjs/platform-fastify stream reply APIs.
Reading entire upload into Buffer on edge - always stream to storage with size limits.
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.
Reviewed by Chris St. John·Last updated Jul 16, 2026