Tutorials
Handling Large File Uploads with Node.js Streams
Buffering a 2GB upload into memory is a great way to meet your on-call rotation. Streams fix it in about thirty lines.

Edwine Nyakundi
Full stack engineer · Jul 19, 2026 · 8 min read
The naive upload handler reads the whole body, then writes it somewhere. It works beautifully until a user uploads a video and your container gets OOM-killed.
Pipe, don't collect
import { pipeline } from class="tok-string">"node:stream/promises";
import { createWriteStream } from class="tok-string">"node:fs";
export async function handleUpload(req, res) {
const target = createWriteStream(class="tok-string">`/tmp/${crypto.randomUUID()}`);
try {
await pipeline(req, target);
res.writeHead(201).end(class="tok-string">"uploaded");
} catch (err) {
target.destroy();
res.writeHead(500).end(class="tok-string">"upload failed");
}
}`pipeline` handles backpressure and cleanup for you. That second part matters more than people expect — a half-written temp file left behind on every failed request is its own outage waiting to happen.
Add a size guard
import { Transform } from class="tok-string">"node:stream";
const limit = (max) => {
let seen = 0;
return new Transform({
transform(chunk, _enc, cb) {
seen += chunk.length;
if (seen > max) return cb(new Error(class="tok-string">"payload too large"));
cb(null, chunk);
},
});
};Drop that in the middle of the pipeline and you reject oversized uploads before they cost you disk.
Related posts
Building a Type-Safe API Layer in React with TypeScript
Stop sprinkling `any` across your fetch calls. Here's the small, boring pattern I use on every production app to keep server data honest.
Sep 12, 2026 · 9 min read
Four Postgres Indexes I Wish I'd Understood Earlier
A 2.4s query became 11ms after one index. Here's how I reason about B-tree, partial, composite, and GIN indexes now.
Aug 28, 2026 · 11 min read
Growing Into a Senior Engineer Without Burning Out
Nobody gets promoted for working weekends. What actually moved the needle for me was writing things down and saying no more often.
Aug 4, 2026 · 7 min read
Newsletter
Get new posts in your inbox
Deep dives on TypeScript, Postgres, and engineering careers — roughly twice a month. No courses to sell, no spam.