Why Streams Exist
Reading a 2GB file with readFile() loads the entire file into memory before you can do anything with it. A stream instead processes data in small chunks as they arrive, keeping memory usage low regardless of the total size.
Four Types of Streams
| Type | Example |
|---|---|
| Readable | Reading a file, an incoming HTTP request body |
| Writable | Writing to a file, an HTTP response |
| Duplex | Both readable and writable, like a TCP socket |
| Transform | A duplex stream that modifies data as it passes through, like gzip compression |
Reading a File as a Stream
Console Output
Click “Run” to see the console output here.
Piping Streams Together
Console Output
Click “Run” to see the console output here.
Backpressure
If a writable stream can't keep up with an incoming readable stream (like a slow network connection receiving a fast file read), .pipe() automatically pauses the readable side until the writable side catches up — this is called backpressure, and it prevents memory from ballooning unbounded.
Best Practice
Use streams (and .pipe()) for anything involving large files or network data — uploads, downloads, video, log processing — rather than loading everything into memory with the non-streaming fs methods.