Connection reliability
Respect backpressure
Stop writing when the socket buffer fills and resume only after the drain event.
10 minute lesson
A fast producer can outpace a slow receiver. Say your server streams a large file to a client on a slow link: you can read from disk far faster than TCP can deliver. Every byte the socket can’t send yet has to wait somewhere.
That somewhere is Node’s internal write queue. socket.write() never blocks — it queues the chunk and returns a boolean. true means keep going. false means the queued bytes crossed the stream’s highWaterMark threshold (16 KiB by default for sockets). Node queues writes, but an unbounded queue consumes memory, and nothing stops you from ignoring the false.
Backpressure is the discipline of pausing the producer when the consumer falls behind.
Check the return value from write():
if (!socket.write(chunk)) {
source.pause()
socket.once('drain', () => source.resume())
}
source is whatever produces the data — a file stream, another socket. When write() returns false, pause it. The socket emits drain once its queue empties, and you resume.
If you’re just connecting two streams, source.pipe(socket) — or better, pipeline() from node:stream — implements exactly this logic plus error handling. Write it by hand once so you know what pipe is doing for you.
See it happen
Make a deliberately slow client by pausing its reads. Throttle the client or pause its reads, then send a large authorized test stream from the server:
socket.on('data', () => {
socket.pause()
setTimeout(() => socket.resume(), 100)
})
Pausing stops Node from draining the kernel buffer, TCP’s flow control fills the sender’s window, and the server’s queue backs up. Log every write() return value and every drain: you should observe write returning false, a pause, and repeated drain-and-resume cycles.
Now watch process memory during the transfer. With backpressure it stays flat. Comment out the pause() and it climbs with the size of the transfer — that’s the production failure mode: one slow client, one loop writing at full speed, and the process dies with an out-of-memory error while the socket looked perfectly healthy.
Backpressure is flow control inside the process. It does not authorize unlimited payload size or connection count — those need explicit limits, coming next.
Lesson completed