v1.1.0
@morojs/engine 1.1.0
Performance release. The engine now outperforms uWebSockets.js in both benchmark profiles — real-world (no pipelining) and pipelined — on a single thread, with no API changes and no behavior changes.
Numbers
Alternating best-of-rounds vs uWebSockets.js through the full MoroJS stack (wrk, 100 connections, Node 24, Apple M2 Ultra):
| Profile | @morojs/engine | uWebSockets.js |
|---|---|---|
| Real-world (no pipelining) | 94,216 req/s | 91,247 req/s |
| Pipelined ×10 (TechEmpower-style) | 495,440 req/s | 470,520 req/s |
The engine won every round of every profile. Versus 1.0.0, pipelined throughput is 3.4× higher (145k → ~495k) and the real-world path gained ~5%.
What changed
- Pipelined response corking — synchronous responses to pipelined requests now accumulate in a per-connection cork buffer and hit the socket as one write per batch instead of one queued write + event-loop deferral per response. Handlers still run strictly one-at-a-time on a clean stack (request N+1 is surfaced only after handler N returns); async handlers, upgrades, errors, and
Connection: closekeep their existing paths. The buffer is bounded by the write high-water mark. - Zero-allocation hot path on warm connections
- Header parsing reuses header slots (and their string capacities) across requests instead of reallocating and destroying them each request.
- The request snapshot (path, query, method, headers, body) is swapped with the parser rather than copied — the previous request's buffers become the parser's scratch for the next one.
- Responses build into a reusable per-connection buffer and are written straight from it on the fast path — no per-response allocation, no intermediate copy. Oversized buffers (>64 KB) are released so a single large response can't pin memory.
- Prebuilt status lines for hot statuses; the
Connection:header no longer allocates.
- Bounded as before — all caps (
maxHeaders, body/head sizes, write high-water mark, pending-bytes flood cap) apply unchanged; large bodies and responses do not stay pinned to idle keep-alive connections.
Compatibility
- No API changes. Drop-in for 1.0.0; MoroJS picks it up via
^1.0.0. - Same platform/ABI matrix as 1.0.0 (macOS arm64/x64, Linux glibc x64/arm64, Linux musl x64, Windows x64 × Node 20–26), prebuilt with npm provenance.
Verification
- 128 socket-level wire tests (HTTP conformance + edge + hardening + regression, WebSocket, limits, TLS + TLS-hardening, permessage-deflate) — all passing.
- 95-check parser unit suite + WebSocket/deflate unit suites under the C++ harness.
- 234 MoroJS integration tests against this build.
- libFuzzer corpus runs on the modified parser; ASan/UBSan legs run in CI.