Under The Hood
backend nodejs Node.js 20+ (llhttp)

llhttp HTTP Parsing Engine, Keep-Alive Connections, Socket Pooling

Last updated
Prerequisites:
Node.js HTTP client/server basics
Understanding of TCP connections and HTTP parsing
  • nodejs
  • llhttp
  • http-parser
  • keep-alive
  • socket-pooling
  • http

Read at your depth

The practical view

Node's HTTP parsing is done by llhttp, a C++ HTTP parser (TypeScript-compiled-to-C, low-level). It parses incoming HTTP requests/responses quickly with minimal allocation. Keep-alive: HTTP/1.1 connections stay open after a response (Connection: keep-alive), so multiple requests reuse one TCP connection — avoiding TCP handshake + TLS overhead per request. Node's http.Agent implements connection pooling for clients: it keeps free sockets in a pool, reuses them for subsequent requests to the same host, and creates new ones as needed (maxSockets, keepAlive, maxFreeSockets options). Server-side, Node also keeps connections alive for reuse.

The same idea in other frameworks

react equivalent
N/A — Node.js runtime concern.

Legacy vs modern

New connection per request vs keep-alive + Agent pooling

Opening a fresh TCP connection per request pays handshake costs; keep-alive and the Agent's socket pool reuse connections.

before → after
One connection per request (no keep-alive)
http.get(url, cb); // ❌ OLD: fresh TCP+TLS handshake per request
Keep-alive + Agent pooling
const agent = new http.Agent({ keepAlive: true, maxSockets: 10 }); // ✅ NEW

Interview gotchas

Context

This tests the parser design — interviewers want the state-machine/no-allocation rationale and why HTTP parsing is a hot path worth optimizing in native code.

The mechanical answer

llhttp is a state-machine parser written in TypeScript and compiled to C (it generates a compact C state table). It walks the input buffer byte-by-byte with a state machine, emitting callbacks as it recognizes the request line, headers, and body boundaries. Unlike a regex-based or JS-level parser, it avoids per-parse allocations, uses no backtracking, and is small enough to stay in cache. Since HTTP parsing runs for EVERY request, the parser is a critical hot path: a fast, allocation-light parser directly reduces per-request CPU and GC pressure. The state machine also handles streaming input correctly (partial headers, pipelined requests) by remembering its position between chunks.

Trap

The naive answer is 'the parser is fast because it's in C'. The speed comes from the design (state machine, no allocation, no backtracking), and it's compiled from a high-level spec (TypeScript) — the C is generated. Another trap: thinking parsing overhead is negligible — for small requests (typical API calls), parsing can be a meaningful fraction of total request CPU; Node's investment in llhttp is precisely because it matters. Candidates who describe the state-machine design show real understanding.

Under The Hood — a multi-depth technical interview hub.

Third-party licenses Press ⌘ K to search.