DEV Community

Ray Forever
Ray Forever

Posted on

Native HTTP Engine for Node: Performance Benchmarks Against uWS, Bun, Fastify, and Hono

Overview

A native HTTP engine for Node.js has been developed with the goal of providing a faster, built-in alternative to the standard node:http module. This engine is designed to address performance bottlenecks and reduce the overhead of third-party native addons.

Performance Benchmarks

Benchmarks were conducted on a Node 24.11 environment running on an M2 Ultra machine. The testing tool was wrk with 100 connections over a 40-second duration, recording the best result of three runs. All packages were pulled from npm rather than built locally.

Requests per Second

Server Non-pipelined Pipelined ×10
@morojs/engine 105,974 663,735
uWebSockets.js 103,744 647,530
raw Bun.serve 107,119 21,686
raw node:http 69,045 109,538
Hono 56,926 100,278

Observations

  • Non-pipelined Performance: The non-pipelined column appears to be limited by the test machine's maximum capacity, with native transports converging around 105k requests per second. Bun.serve marginally leads in this metric. Adding a framework like Elysia on top of Bun.serve reduces its performance to 96.7k requests per second.
  • Pipelined Performance: The new engine shows a significant advantage in pipelined requests, achieving about a 10% improvement over uWebSockets.js once a framework is integrated. This is attributed to response corking and batching pipeline requests into a single write operation.

A full performance matrix and testing harness are available in the benchmark repository.

Technical Architecture

The engine is built with a C++ core using raw V8 bindings instead of N-API. The primary design principle is to minimize boundary crossings between C++ and JavaScript.

  • General-purpose bindings typically perform 10-20 JavaScript crossings per request.
  • This engine reduces crossings to 2-4 per request by batching request snapshots and response writes.

Corking and Optimization

Corking is central to the performance gains, particularly for pipelined requests. Version 1.1.0 introduced batching of an entire pipeline into a single write, along with a zero-allocation hot path, resulting in a 3.7x improvement in pipelined performance over version 1.0.0.

Trade-offs and Build Strategy

  • N-API vs. Raw V8: While N-API offers a stable ABI and easier maintenance, it did not achieve the desired performance levels. Raw V8 bindings were chosen for performance, at the cost of ABI-locking.
  • ABI Compatibility: To manage the ABI matrix, the project builds and ships precompiled binaries from tagged CI builds with npm provenance. This ensures day-one compatibility with new Node.js releases, avoiding delays often associated with third-party native addons.
  • Fallback Mechanism: In environments where a prebuilt binary is not available, the engine gracefully falls back to node:http and logs the reason via app.engine.fallbackReason.

Security

The engine has zero external dependencies. It handles query, cookie, multipart, and route-pattern parsing directly within the framework.

  • Fuzzing: These parsers are property-fuzzed with a fixed seed on every push and nightly with a rotating seed at 500,000 iterations per property.
  • C++ Parser: The underlying C++ HTTP parser has its own dedicated fuzzing harness within the engine repository.

Availability

This engine is the default server for a framework maintained by the author. The source code and project repositories are publicly available.

Top comments (0)