Skip to content

C++ Engine Architecture & Multi-Threading โ€‹

Velociradix is built around a hybrid Multi-Threaded Native C++17 Engine coupled with a single-threaded V8 JavaScript execution layer.


๐Ÿงต 1. Multi-Threading & Socket Load Balancing (SO_REUSEPORT) โ€‹

Standard Node.js applications run on a single main thread, which limits network socket processing to a single CPU core unless complex cluster modules are configured.

Velociradix solves this natively at the kernel level:

text
 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
 โ”‚               OS Network Sockets & TCP Kernel             โ”‚
 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                               โ”‚ SO_REUSEPORT Kernel Load-Balancing
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚                      โ”‚                      โ”‚
 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
 โ”‚ C++ Worker Thread 1โ”‚ โ”‚ C++ Worker Thread 2โ”‚ โ”‚ C++ Worker Thread Nโ”‚
 โ”‚   (kqueue/epoll)   โ”‚ โ”‚   (kqueue/epoll)   โ”‚ โ”‚   (kqueue/epoll)   โ”‚
 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
            โ”‚                      โ”‚                      โ”‚
            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                   โ”‚ Lock-Free N-API Queue
                        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                        โ”‚   V8 Main Thread    โ”‚
                        โ”‚ (JS Middleware/App) โ”‚
                        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Key Multi-Threading Principles: โ€‹

  1. Kernel-Level Distribution (SO_REUSEPORT): Velociradix configures underlying TCP sockets with SO_REUSEPORT. The OS kernel automatically load-balances incoming TCP connections across multiple C++ worker threads running on dedicated CPU cores.

  2. Off-Main-Thread Processing:

    • Socket I/O operations, HTTP header parsing, and static route matching run 100% inside native C++ worker threads.
    • Up to 80% of request execution overhead is offloaded from the Node.js main thread.
  3. C++ Fast-Path Threads: For routes registered with app.fastGet() or app.fastPost(), response bytes are written from C++ worker threads without waking V8. That path is a preformatted body, not a JS handler. Measured ~114k req/s on the same autocannon shape as the JS table โ€” see benchmarks.

๐Ÿ› ๏ธ Setting Thread Count in JavaScript: โ€‹

You can specify the number of C++ worker threads directly using app.setWorkers(count):

js
import os from "node:os";
import { createApp } from "velociradix";

const app = createApp();

// Set worker threads to match available CPU cores
app.setWorkers(os.cpus().length);

app.listen(3000);

โšก 2. Lock-Free Native Object Pooling & V8 Monomorphic Shapes โ€‹

To maintain low latency and eliminate Garbage Collection (GC) pauses:

  • PendingCall handle table: C++ PendingCall objects are pooled under a mutex. JavaScript holds napi_external tokens (slot + generation), never a heap address cast to Number. A stale handle cannot write into a recycled request.
  • V8 Monomorphic Context Pool: JavaScript Context objects are pre-allocated and recycled. Object hidden classes (shapes) remain strictly monomorphic, preventing V8 de-optimizations.

๐Ÿ“Š 3. Event Loop Comparison โ€‹

MechanismStandard Node.js (http)Velociradix Engine
Socket HandlingSingle Thread (libuv)Multi-Threaded C++ Workers (kqueue/epoll)
Header Parsingllhttp on JS threadZero-copy string_view on C++ worker thread
Route MatchingJS String comparisonsZero-allocation C++ Radix Trie
Fast-Path SupportโŒ Noneโœ… Direct C++ socket write (fastGet, ~114k RPS in our table)
GC OverheadHigh (creates new objects per req)Zero (recycled monomorphic Context pool)

๐Ÿ›ก๏ธ 4. Parser Hardening & Socket Tuning โ€‹

The C++ HTTP parser is a custom implementation, not llhttp. That is a trust decision: Trust. It runs on worker threads before any JavaScript handler:

  • Rejects request smuggling (Content-Length conflicts, Transfer-Encoding + Content-Length, obs-fold, LF-only framing).
  • Requires Host on HTTP/1.1; rejects TRACE/CONNECT; caps header block (32 KiB / 100 headers) and URI length (8 KiB).
  • Closes Slowloris connections after 10s of incomplete headers; keep-alive idle connections after 30s. Max 16,384 connections per worker. Any Transfer-Encoding is rejected.
  • Strips CR/LF/NUL from outbound header names and values.
  • Accepted sockets use TCP_NODELAY (Linux also accept4 + TCP_QUICKACK) so small responses flush without Nagle delay.
  • Peer IPv4 is captured at accept() and exposed as ctx.req.remoteAddress.
  • JS request handles are napi_external tokens (slot + generation). A stale JS value cannot write into a recycled PendingCall.

Released under the MIT License.