[NodeCongress2024] Deep Dive into Undici: Architecture, Performance, and the Future of HTTP in Node.js
Lecturer: Matteo Collina
Matteo Collina is an internationally recognized expert in Node.js and open-source architecture, serving as the Co-Founder and CTO of Platformatic. He holds a Ph. D. in “Application Platforms for the Internet of Things”. A member of the Node.js Technical Steering Committee (TSC), he is a major contributor to the platform’s core, with a focus on streams, diagnostics, and the HTTP stack. He is the original author of the highly successful, high-performance web framework Fastify and the ultra-fast JSON logger Pino. His open-source modules are downloaded billions of times annually.
- Institutional Profile: Matteo Collina
- Publications: Matteo Collina’s talks, articles, workshops, certificates – GitNation
Abstract
This article presents a technical analysis of Undici, the high-performance, standards-compliant HTTP/1.1 client that serves as the foundation for the native fetch()
API in Node.js. It explains the motivation for Undici’s creation—addressing critical performance and protocol deficiencies in the legacy Node.js stack. The article details the core architectural components, particularly the Client and Dispatcher abstractions, and explains how Undici achieves superior efficiency through advanced connection management and HTTP/1.1 pipelining. The final analysis explores the methodological implications of Undici’s modularity, including enabling zero-overhead internal testing and powering highly efficient modular monolith and microservice runtimes.
Context: Limitations of the Legacy Node.js HTTP Stack
The legacy Node.js HTTP client suffered from several long-standing limitations, primarily in performance and compliance with modern standards. Specifically, it lacked proper support for HTTP/1.1 pipelining—the ability to send multiple requests sequentially over a single connection without waiting for the first response. Furthermore, its connection pool management was inefficient, often failing to enforce proper limits, leading to potential resource exhaustion and performance bottlenecks. Undici was developed to resolve these architectural deficiencies, becoming the native engine for fetch()
within Node.js core.
Architecture and Methodology of Undici
Undici’s design is centered around optimizing connection usage and abstracting the request lifecycle:
- The Client and Connection Pools: The core component is the
Client
, which is scoped to a single origin (protocol, hostname, and port). The Client manages a pool of TCP connections and is responsible for implementing the efficiency of the HTTP protocol. - Pipelining for Performance: Undici explicitly implements HTTP/1.1 pipelining. This methodology permits the efficient use of the network and is essential for maximum HTTP/1.1 performance, particularly when connecting to modern servers that support the feature.
- The Dispatcher Abstraction: Undici utilizes a pluggable
Dispatcher
interface. This abstraction governs the process of taking a request, managing connection logic, and writing the request to a socket. Key Dispatcher implementations include the standardClient
(for a single origin) and theAgent
(for multiple origins). - Connection Management: The pooling mechanism employs a strategy to retire connections gracefully to allow DNS changes and resource rotation, contrasting with legacy systems that often held connections indefinitely.
Consequences and Architectural Innovations
Undici’s modular and abstracted architecture has led to significant innovations beyond core HTTP performance:
- In-Process Request Testing: The Dispatcher model allows for the implementation of a
MockClient
(accessible via thelight-my-request
module), which completely bypasses the network stack. This permits the injection of HTTP requests directly into a running Node.js server within the same process, enabling zero-overhead, high-speed unit and integration testing without opening any actual sockets. - Internal Mesh Networking: The architecture enables a unique pattern for running multiple microservices within a single process. Using a custom dispatcher (
fastify-undici-dispatcher
), internal HTTP requests can be routed directly to other services (e.g., Fastify instances) running in the same process via an in-memory mesh network, completely bypassing the network layer for inter-service communication. This methodology, employed in the Platformatic runtime, allows developers to transition from a modular monolith to a microservice architecture with minimal code changes, retaining maximum performance for inter-service calls.
Links
- Lecture Video: Deep Dive into Undici – Matteo Collina, Node Congress 2024
- Lecturer’s X/Twitter: https://twitter.com/matteocollina
- Organization: https://platformatic.dev/
Hashtags: #Undici #NodeJS #HTTPClient #Fastify #Microservices #PerformanceEngineering #Platformatic