Stream xử lý data theo chunks — memory efficiency cực cao: đọc file 1GB chỉ tốn ~64KB RAM (default highWaterMark) thay vì 1GB.
- Bốn loại: Readable (fs.createReadStream, HTTP req, process.stdin), Writable (fs.createWriteStream, HTTP res, process.stdout), Duplex (TCP socket — đọc và ghi độc lập), Transform (zlib.createGzip, crypto.createCipher — transform data flow through).
pipeline()API (Node.js 10+) thay thế.pipe():await pipeline(readStream, transformStream, writeStream)— tự cleanup và propagate errors (.pipe()không handle errors tốt). - Stream consumers với
for await...of:for await (const chunk of readableStream) { process(chunk); }— ergonomic nhất.
Ví dụ thực: serve 1GB file với 0 timeout và thấp RAM: const src = fs.createReadStream(filePath); const gzip = zlib.createGzip(); await pipeline(src, gzip, res) — data chảy qua, không buffer toàn bộ.
Streams process data in chunks — extreme memory efficiency: reading a 1GB file uses only ~64KB of RAM (default highWaterMark) instead of 1GB.
- Four types: Readable (fs.createReadStream, HTTP req, process.stdin), Writable (fs.createWriteStream, HTTP res, process.stdout), Duplex (TCP socket — read and write independently), Transform (zlib.createGzip, crypto.createCipher — transforms data flowing through).
pipeline()API (Node.js 10+) replaces.pipe():await pipeline(readStream, transformStream, writeStream)— auto-cleanup and error propagation (.pipe()doesn't handle errors well). - Stream consumers with
for await...of:for await (const chunk of readableStream) { process(chunk); }— the most ergonomic approach. - Practical example: serve a 1GB file with zero timeout and minimal RAM:
const src = fs.createReadStream(filePath); const gzip = zlib.createGzip(); await pipeline(src, gzip, res)— data flows through without buffering the entire file. - Backpressure: when the Writable is slower than the Readable,
pipelineautomatically pauses the Readable to prevent OOM — this is why you should not use.pipe()manually in production.