streams-backpressureAnswer last reviewed July 2026

When you destroy a stream, what actually happens under the hood? And when a socket dies mid-transfer, how do you clean up properly?

A strong answer keeps end, finish, and close straight, knows what destroy releases, and reaches for finished or pipeline instead of hand-wiring terminal events

What an AI-prepared candidate might say

destroy() is the forceful teardown, basically. It releases the underlying resource, the socket or the file descriptor, emits an 'error' if you passed one in, and then emits 'close'. After that the stream is unusable and further writes fail. The events break down roughly like, 'end' fires on a readable once all the data has been consumed, 'finish' fires on a writable once everything you wrote has been flushed to the underlying system, and 'close' fires when the stream and its resource are actually released. When a socket dies mid-transfer, the streams attached to it need to get destroyed too or they leak. Which is why the advice is stream.pipeline, or stream.finished for a single stream. They watch every terminal path, error, premature close, completion, and destroy the chain instead of leaving pieces open. ERR_STREAM_PREMATURE_CLOSE is what you get when a stream closed before it signaled completion, I believe.

Senior
Locked

The destroy sequence walked step by step, the end, finish, and close ladder on both stream types, and what premature close is really telling you.

Unlock the depth
Staff
Locked

The CLOSE_WAIT pileup that points at missing destroys, the durability-versus-finish gap on file streams, and how to chaos-test the disconnect path in CI.

Unlock the depth
Follow-up chain
When you destroy a stream, what actually happens under the hood? And when a socket dies mid-transfer, how do you clean up properly? | NodeBook