Node.js
This page summarizes Node.js benchmark runs for Knitting 0.1.24 on
node 24.12.0 (arm64-darwin), recorded in March 2026.
IPC (Node)
Section titled “IPC (Node)”This benchmark measures round-trip communication between the main thread and workers using different transports. Knitting has the lowest overhead in this setup:
1message: Knitting is about5.2xfaster than workerpostMessage,12xfaster than WebSocket, and29xfaster than HTTP.25messages: Knitting is about3.5xfaster than workerpostMessage.50messages: Knitting is about3.3xfaster than workerpostMessage.
clk: ~3.67 GHzcpu: Apple M3 Ultraruntime: node 24.12.0 (arm64-darwin)
| • knitting | avg | min | p75 | p99 | max || --------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || 1 thread → (1) | ` 2.22 µs/iter` | ` 1.12 µs` | ` 2.63 µs` | ` 5.54 µs` | ` 1.27 ms` || 1 thread → (25) | ` 15.99 µs/iter` | ` 14.33 µs` | ` 16.56 µs` | ` 17.15 µs` | ` 19.87 µs` || 1 thread → (50) | ` 30.67 µs/iter` | ` 28.07 µs` | ` 31.19 µs` | ` 32.16 µs` | ` 33.21 µs` |clk: ~3.71 GHzcpu: Apple M3 Ultraruntime: node 24.12.0 (arm64-darwin)
| • websocket | avg | min | p75 | p99 | max || ------------ | ---------------- | ----------- | ----------- | ----------- | ----------- || local → (1) | ` 26.83 µs/iter` | ` 12.83 µs` | ` 26.96 µs` | ` 85.25 µs` | `468.58 µs` || local → (25) | `183.39 µs/iter` | `130.33 µs` | `195.83 µs` | `272.71 µs` | `976.96 µs` || local → (50) | `345.79 µs/iter` | `252.42 µs` | `363.46 µs` | `456.25 µs` | ` 1.45 ms` |clk: ~3.70 GHzcpu: Apple M3 Ultraruntime: node 24.12.0 (arm64-darwin)
| • worker | avg | min | p75 | p99 | max || ------------------ | ---------------- | ----------- | ----------- | ----------- | ----------- || postMessage → (1) | ` 11.49 µs/iter` | ` 7.29 µs` | ` 12.00 µs` | ` 33.21 µs` | `344.50 µs` || postMessage → (25) | ` 56.73 µs/iter` | ` 55.91 µs` | ` 56.83 µs` | ` 57.24 µs` | ` 57.76 µs` || postMessage → (50) | `102.10 µs/iter` | ` 68.83 µs` | `105.63 µs` | `221.17 µs` | ` 3.49 ms` |clk: ~3.68 GHzcpu: Apple M3 Ultraruntime: node 24.12.0 (arm64-darwin)
| • http | avg | min | p75 | p99 | max || ------------ | ---------------- | ----------- | ----------- | ----------- | ----------- || local → (1) | ` 65.42 µs/iter` | ` 38.42 µs` | ` 66.13 µs` | `174.38 µs` | `601.33 µs` || local → (25) | `966.49 µs/iter` | `859.96 µs` | ` 1.01 ms` | ` 1.22 ms` | ` 2.04 ms` || local → (50) | ` 1.90 ms/iter` | ` 1.71 ms` | ` 1.99 ms` | ` 2.17 ms` | ` 2.64 ms` |Knitting vs Worker (Node)
Section titled “Knitting vs Worker (Node)”These charts compare the same payload types sent through Knitting and worker_threads.
One message
Section titled “One message”With a single value per call, Knitting is faster in these measurements:
- For small primitives, Knitting is roughly
10-14xfaster than workerpostMessage. - Worker
postMessagestays near~10 µs/itereven for tiny payloads. - For larger payloads, Knitting still holds around a
4xadvantage (for example, big object:4.15 µsvs15.74 µs).
clk: ~3.71 GHzcpu: Apple M3 Ultraruntime: node 24.12.0 (arm64-darwin)
| • knitting 1 | avg | min | p75 | p99 | max || --------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || number -> (1) | ` 1.19 µs/iter` | `500.00 ns` | ` 1.54 µs` | ` 2.88 µs` | ` 1.33 ms` || bigint small -> (1) | ` 1.05 µs/iter` | `551.27 ns` | ` 1.39 µs` | ` 1.65 µs` | ` 1.67 µs` || bigint large -> (1) | ` 2.36 µs/iter` | ` 1.29 µs` | ` 2.54 µs` | ` 5.83 µs` | ` 1.24 ms` || boolean true -> (1) | ` 1.10 µs/iter` | `534.90 ns` | ` 1.46 µs` | ` 1.59 µs` | ` 1.61 µs` || boolean false -> (1) | ` 1.06 µs/iter` | `531.85 ns` | ` 1.49 µs` | ` 1.61 µs` | ` 1.62 µs` || undefined -> (1) | ` 1.05 µs/iter` | `531.94 ns` | ` 1.44 µs` | ` 1.60 µs` | ` 1.65 µs` || null -> (1) | ` 1.03 µs/iter` | `534.34 ns` | ` 1.35 µs` | ` 1.67 µs` | ` 1.90 µs` || string -> (1) | ` 1.57 µs/iter` | `583.00 ns` | ` 2.13 µs` | ` 3.29 µs` | ` 1.26 ms` || json object -> (1) | ` 3.64 µs/iter` | ` 2.50 µs` | ` 3.75 µs` | ` 8.67 µs` | ` 1.27 ms` || json array -> (1) | ` 4.73 µs/iter` | ` 4.28 µs` | ` 4.90 µs` | ` 5.21 µs` | ` 5.22 µs` || Uint8Array -> (1) | ` 3.11 µs/iter` | ` 1.17 µs` | ` 3.83 µs` | ` 8.08 µs` | ` 1.25 ms` || ArrayBuffer -> (1) | ` 3.24 µs/iter` | ` 1.50 µs` | ` 4.21 µs` | ` 8.50 µs` | ` 1.27 ms` || Buffer -> (1) | ` 2.87 µs/iter` | ` 1.17 µs` | ` 3.83 µs` | ` 7.25 µs` | ` 1.24 ms` || string huge -> (1) | ` 3.73 µs/iter` | ` 2.00 µs` | ` 4.38 µs` | ` 8.75 µs` | ` 1.25 ms` || Int32Array -> (1) | ` 2.84 µs/iter` | ` 1.80 µs` | ` 3.32 µs` | ` 3.78 µs` | ` 3.86 µs` || Float64Array -> (1) | ` 3.37 µs/iter` | ` 1.46 µs` | ` 4.17 µs` | ` 8.79 µs` | ` 1.27 ms` || BigInt64Array -> (1) | ` 2.70 µs/iter` | ` 1.77 µs` | ` 3.19 µs` | ` 3.69 µs` | ` 3.87 µs` || BigUint64Array -> (1) | ` 3.03 µs/iter` | ` 1.21 µs` | ` 3.83 µs` | ` 7.58 µs` | ` 1.26 ms` || DataView -> (1) | ` 2.89 µs/iter` | ` 1.87 µs` | ` 3.37 µs` | ` 3.77 µs` | ` 3.85 µs` || Date -> (1) | ` 1.34 µs/iter` | `542.00 ns` | ` 1.63 µs` | ` 2.71 µs` | ` 1.24 ms` |
| • knitting 100 | avg | min | p75 | p99 | max || ----------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || number -> (100) | ` 27.35 µs/iter` | ` 15.42 µs` | ` 33.79 µs` | ` 60.38 µs` | `222.08 µs` || bigint small -> (100) | ` 26.77 µs/iter` | ` 24.24 µs` | ` 28.06 µs` | ` 28.61 µs` | ` 31.03 µs` || bigint large -> (100) | ` 72.11 µs/iter` | ` 53.50 µs` | ` 73.83 µs` | `137.13 µs` | ` 1.35 ms` || boolean true -> (100) | ` 28.12 µs/iter` | ` 25.30 µs` | ` 29.23 µs` | ` 31.10 µs` | ` 35.62 µs` || boolean false -> (100) | ` 27.33 µs/iter` | ` 20.98 µs` | ` 29.51 µs` | ` 29.70 µs` | ` 32.56 µs` || undefined -> (100) | ` 29.03 µs/iter` | ` 22.39 µs` | ` 31.83 µs` | ` 32.06 µs` | ` 32.95 µs` || null -> (100) | ` 28.28 µs/iter` | ` 25.01 µs` | ` 29.89 µs` | ` 30.11 µs` | ` 30.44 µs` || string -> (100) | ` 37.10 µs/iter` | ` 33.71 µs` | ` 38.45 µs` | ` 39.78 µs` | ` 40.58 µs` || json object -> (100) | `125.75 µs/iter` | `106.08 µs` | `128.67 µs` | `216.33 µs` | ` 1.42 ms` || json array -> (100) | `178.12 µs/iter` | `154.33 µs` | `183.25 µs` | `290.88 µs` | ` 1.55 ms` || Uint8Array -> (100) | `108.89 µs/iter` | ` 54.00 µs` | `137.63 µs` | `209.29 µs` | ` 2.93 ms` || ArrayBuffer -> (100) | `119.46 µs/iter` | ` 63.50 µs` | `145.71 µs` | `222.29 µs` | ` 2.59 ms` || Buffer -> (100) | `103.74 µs/iter` | ` 54.42 µs` | `143.88 µs` | `207.08 µs` | ` 2.88 ms` || string huge -> (100) | `167.81 µs/iter` | `111.54 µs` | `208.21 µs` | `265.50 µs` | ` 1.44 ms` || Int32Array -> (100) | `116.92 µs/iter` | ` 55.12 µs` | `143.83 µs` | `214.25 µs` | ` 3.00 ms` || Float64Array -> (100) | `120.60 µs/iter` | ` 61.96 µs` | `139.67 µs` | `224.54 µs` | ` 2.08 ms` || BigInt64Array -> (100) | `107.85 µs/iter` | `102.95 µs` | `109.66 µs` | `111.51 µs` | `113.46 µs` || BigUint64Array -> (100) | `112.46 µs/iter` | ` 56.50 µs` | `139.96 µs` | `207.25 µs` | ` 3.15 ms` || DataView -> (100) | `109.26 µs/iter` | ` 59.25 µs` | `140.21 µs` | `214.38 µs` | ` 3.14 ms` || Date -> (100) | ` 33.41 µs/iter` | ` 31.27 µs` | ` 33.97 µs` | ` 35.82 µs` | ` 36.27 µs` |
| • worker 1 | avg | min | p75 | p99 | max || --------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || number -> (1) | ` 11.13 µs/iter` | ` 11.09 µs` | ` 11.15 µs` | ` 11.18 µs` | ` 11.19 µs` || bigint small -> (1) | ` 11.09 µs/iter` | ` 10.99 µs` | ` 11.11 µs` | ` 11.13 µs` | ` 11.15 µs` || bigint large -> (1) | ` 11.06 µs/iter` | ` 10.99 µs` | ` 11.07 µs` | ` 11.10 µs` | ` 11.12 µs` || boolean true -> (1) | ` 11.09 µs/iter` | ` 11.02 µs` | ` 11.11 µs` | ` 11.14 µs` | ` 11.18 µs` || boolean false -> (1) | ` 11.07 µs/iter` | ` 11.02 µs` | ` 11.10 µs` | ` 11.10 µs` | ` 11.11 µs` || undefined -> (1) | ` 11.05 µs/iter` | ` 11.03 µs` | ` 11.05 µs` | ` 11.07 µs` | ` 11.09 µs` || null -> (1) | ` 11.09 µs/iter` | ` 11.03 µs` | ` 11.11 µs` | ` 11.13 µs` | ` 11.13 µs` || string -> (1) | ` 11.09 µs/iter` | ` 11.04 µs` | ` 11.12 µs` | ` 11.13 µs` | ` 11.15 µs` || json object -> (1) | ` 14.88 µs/iter` | ` 14.63 µs` | ` 14.86 µs` | ` 14.93 µs` | ` 15.82 µs` || json array -> (1) | ` 18.70 µs/iter` | ` 18.45 µs` | ` 18.65 µs` | ` 18.79 µs` | ` 19.73 µs` || Uint8Array -> (1) | ` 12.09 µs/iter` | ` 11.91 µs` | ` 12.13 µs` | ` 12.19 µs` | ` 12.35 µs` || ArrayBuffer -> (1) | ` 11.85 µs/iter` | ` 11.67 µs` | ` 11.90 µs` | ` 12.00 µs` | ` 12.10 µs` || Buffer -> (1) | ` 14.02 µs/iter` | ` 13.70 µs` | ` 14.18 µs` | ` 14.21 µs` | ` 14.29 µs` || string huge -> (1) | ` 11.23 µs/iter` | ` 11.17 µs` | ` 11.27 µs` | ` 11.34 µs` | ` 11.34 µs` || Int32Array -> (1) | ` 12.08 µs/iter` | ` 11.94 µs` | ` 12.11 µs` | ` 12.31 µs` | ` 12.34 µs` || Float64Array -> (1) | ` 12.12 µs/iter` | ` 11.99 µs` | ` 12.21 µs` | ` 12.25 µs` | ` 12.30 µs` || BigInt64Array -> (1) | ` 12.11 µs/iter` | ` 11.91 µs` | ` 12.17 µs` | ` 12.33 µs` | ` 12.41 µs` || BigUint64Array -> (1) | ` 12.10 µs/iter` | ` 11.95 µs` | ` 12.18 µs` | ` 12.23 µs` | ` 12.29 µs` || DataView -> (1) | ` 12.67 µs/iter` | ` 12.02 µs` | ` 13.01 µs` | ` 13.15 µs` | ` 13.17 µs` || Date -> (1) | ` 11.41 µs/iter` | ` 5.92 µs` | ` 12.00 µs` | ` 32.67 µs` | `168.46 µs` |
| • worker 100 | avg | min | p75 | p99 | max || ----------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || number -> (100) | `173.42 µs/iter` | `121.71 µs` | `177.04 µs` | `333.04 µs` | ` 3.54 ms` || bigint small -> (100) | `178.73 µs/iter` | `122.33 µs` | `183.04 µs` | `333.79 µs` | ` 3.50 ms` || bigint large -> (100) | `171.77 µs/iter` | `123.63 µs` | `175.42 µs` | `325.08 µs` | ` 3.16 ms` || boolean true -> (100) | `168.30 µs/iter` | `119.96 µs` | `172.38 µs` | `321.25 µs` | ` 3.08 ms` || boolean false -> (100) | `168.24 µs/iter` | `119.42 µs` | `171.92 µs` | `327.38 µs` | ` 3.18 ms` || undefined -> (100) | `174.87 µs/iter` | `122.58 µs` | `180.38 µs` | `324.38 µs` | ` 3.31 ms` || null -> (100) | `177.45 µs/iter` | `122.75 µs` | `183.29 µs` | `318.17 µs` | ` 3.12 ms` || string -> (100) | `172.13 µs/iter` | `121.83 µs` | `175.33 µs` | `311.46 µs` | ` 3.44 ms` || json object -> (100) | `349.71 µs/iter` | `272.13 µs` | `358.25 µs` | `539.25 µs` | ` 3.52 ms` || json array -> (100) | `518.73 µs/iter` | `409.38 µs` | `542.92 µs` | `754.54 µs` | ` 3.59 ms` || Uint8Array -> (100) | `242.72 µs/iter` | `171.54 µs` | `253.50 µs` | `506.21 µs` | ` 2.42 ms` || ArrayBuffer -> (100) | `229.70 µs/iter` | `160.50 µs` | `239.67 µs` | `470.63 µs` | ` 2.41 ms` || Buffer -> (100) | `354.02 µs/iter` | `222.83 µs` | `376.63 µs` | `974.71 µs` | ` 1.47 ms` || string huge -> (100) | `197.79 µs/iter` | `141.29 µs` | `197.08 µs` | `371.71 µs` | ` 2.56 ms` || Int32Array -> (100) | `243.54 µs/iter` | `169.13 µs` | `254.42 µs` | `512.29 µs` | ` 2.56 ms` || Float64Array -> (100) | `243.76 µs/iter` | `170.29 µs` | `254.00 µs` | `541.63 µs` | ` 2.44 ms` || BigInt64Array -> (100) | `242.08 µs/iter` | `170.46 µs` | `252.08 µs` | `527.83 µs` | ` 2.48 ms` || BigUint64Array -> (100) | `241.30 µs/iter` | `168.63 µs` | `253.17 µs` | `481.75 µs` | ` 2.53 ms` || DataView -> (100) | `240.07 µs/iter` | `169.00 µs` | `250.58 µs` | `529.42 µs` | ` 2.49 ms` || Date -> (100) | `174.26 µs/iter` | `124.38 µs` | `178.88 µs` | `325.83 µs` | ` 3.36 ms` |100 messages
Section titled “100 messages”At 100 messages per iteration:
- Primitive payloads are
~6-8xfaster with Knitting. - Heavier payloads are about
~2.4-4.2xfaster. - Batching improves throughput for both, but Knitting has lower overhead across the tested payload types.
clk: ~3.71 GHzcpu: Apple M3 Ultraruntime: node 24.12.0 (arm64-darwin)
| • knitting 1 | avg | min | p75 | p99 | max || --------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || number -> (1) | ` 1.19 µs/iter` | `500.00 ns` | ` 1.54 µs` | ` 2.88 µs` | ` 1.33 ms` || bigint small -> (1) | ` 1.05 µs/iter` | `551.27 ns` | ` 1.39 µs` | ` 1.65 µs` | ` 1.67 µs` || bigint large -> (1) | ` 2.36 µs/iter` | ` 1.29 µs` | ` 2.54 µs` | ` 5.83 µs` | ` 1.24 ms` || boolean true -> (1) | ` 1.10 µs/iter` | `534.90 ns` | ` 1.46 µs` | ` 1.59 µs` | ` 1.61 µs` || boolean false -> (1) | ` 1.06 µs/iter` | `531.85 ns` | ` 1.49 µs` | ` 1.61 µs` | ` 1.62 µs` || undefined -> (1) | ` 1.05 µs/iter` | `531.94 ns` | ` 1.44 µs` | ` 1.60 µs` | ` 1.65 µs` || null -> (1) | ` 1.03 µs/iter` | `534.34 ns` | ` 1.35 µs` | ` 1.67 µs` | ` 1.90 µs` || string -> (1) | ` 1.57 µs/iter` | `583.00 ns` | ` 2.13 µs` | ` 3.29 µs` | ` 1.26 ms` || json object -> (1) | ` 3.64 µs/iter` | ` 2.50 µs` | ` 3.75 µs` | ` 8.67 µs` | ` 1.27 ms` || json array -> (1) | ` 4.73 µs/iter` | ` 4.28 µs` | ` 4.90 µs` | ` 5.21 µs` | ` 5.22 µs` || Uint8Array -> (1) | ` 3.11 µs/iter` | ` 1.17 µs` | ` 3.83 µs` | ` 8.08 µs` | ` 1.25 ms` || ArrayBuffer -> (1) | ` 3.24 µs/iter` | ` 1.50 µs` | ` 4.21 µs` | ` 8.50 µs` | ` 1.27 ms` || Buffer -> (1) | ` 2.87 µs/iter` | ` 1.17 µs` | ` 3.83 µs` | ` 7.25 µs` | ` 1.24 ms` || string huge -> (1) | ` 3.73 µs/iter` | ` 2.00 µs` | ` 4.38 µs` | ` 8.75 µs` | ` 1.25 ms` || Int32Array -> (1) | ` 2.84 µs/iter` | ` 1.80 µs` | ` 3.32 µs` | ` 3.78 µs` | ` 3.86 µs` || Float64Array -> (1) | ` 3.37 µs/iter` | ` 1.46 µs` | ` 4.17 µs` | ` 8.79 µs` | ` 1.27 ms` || BigInt64Array -> (1) | ` 2.70 µs/iter` | ` 1.77 µs` | ` 3.19 µs` | ` 3.69 µs` | ` 3.87 µs` || BigUint64Array -> (1) | ` 3.03 µs/iter` | ` 1.21 µs` | ` 3.83 µs` | ` 7.58 µs` | ` 1.26 ms` || DataView -> (1) | ` 2.89 µs/iter` | ` 1.87 µs` | ` 3.37 µs` | ` 3.77 µs` | ` 3.85 µs` || Date -> (1) | ` 1.34 µs/iter` | `542.00 ns` | ` 1.63 µs` | ` 2.71 µs` | ` 1.24 ms` |
| • knitting 100 | avg | min | p75 | p99 | max || ----------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || number -> (100) | ` 27.35 µs/iter` | ` 15.42 µs` | ` 33.79 µs` | ` 60.38 µs` | `222.08 µs` || bigint small -> (100) | ` 26.77 µs/iter` | ` 24.24 µs` | ` 28.06 µs` | ` 28.61 µs` | ` 31.03 µs` || bigint large -> (100) | ` 72.11 µs/iter` | ` 53.50 µs` | ` 73.83 µs` | `137.13 µs` | ` 1.35 ms` || boolean true -> (100) | ` 28.12 µs/iter` | ` 25.30 µs` | ` 29.23 µs` | ` 31.10 µs` | ` 35.62 µs` || boolean false -> (100) | ` 27.33 µs/iter` | ` 20.98 µs` | ` 29.51 µs` | ` 29.70 µs` | ` 32.56 µs` || undefined -> (100) | ` 29.03 µs/iter` | ` 22.39 µs` | ` 31.83 µs` | ` 32.06 µs` | ` 32.95 µs` || null -> (100) | ` 28.28 µs/iter` | ` 25.01 µs` | ` 29.89 µs` | ` 30.11 µs` | ` 30.44 µs` || string -> (100) | ` 37.10 µs/iter` | ` 33.71 µs` | ` 38.45 µs` | ` 39.78 µs` | ` 40.58 µs` || json object -> (100) | `125.75 µs/iter` | `106.08 µs` | `128.67 µs` | `216.33 µs` | ` 1.42 ms` || json array -> (100) | `178.12 µs/iter` | `154.33 µs` | `183.25 µs` | `290.88 µs` | ` 1.55 ms` || Uint8Array -> (100) | `108.89 µs/iter` | ` 54.00 µs` | `137.63 µs` | `209.29 µs` | ` 2.93 ms` || ArrayBuffer -> (100) | `119.46 µs/iter` | ` 63.50 µs` | `145.71 µs` | `222.29 µs` | ` 2.59 ms` || Buffer -> (100) | `103.74 µs/iter` | ` 54.42 µs` | `143.88 µs` | `207.08 µs` | ` 2.88 ms` || string huge -> (100) | `167.81 µs/iter` | `111.54 µs` | `208.21 µs` | `265.50 µs` | ` 1.44 ms` || Int32Array -> (100) | `116.92 µs/iter` | ` 55.12 µs` | `143.83 µs` | `214.25 µs` | ` 3.00 ms` || Float64Array -> (100) | `120.60 µs/iter` | ` 61.96 µs` | `139.67 µs` | `224.54 µs` | ` 2.08 ms` || BigInt64Array -> (100) | `107.85 µs/iter` | `102.95 µs` | `109.66 µs` | `111.51 µs` | `113.46 µs` || BigUint64Array -> (100) | `112.46 µs/iter` | ` 56.50 µs` | `139.96 µs` | `207.25 µs` | ` 3.15 ms` || DataView -> (100) | `109.26 µs/iter` | ` 59.25 µs` | `140.21 µs` | `214.38 µs` | ` 3.14 ms` || Date -> (100) | ` 33.41 µs/iter` | ` 31.27 µs` | ` 33.97 µs` | ` 35.82 µs` | ` 36.27 µs` |
| • worker 1 | avg | min | p75 | p99 | max || --------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || number -> (1) | ` 11.13 µs/iter` | ` 11.09 µs` | ` 11.15 µs` | ` 11.18 µs` | ` 11.19 µs` || bigint small -> (1) | ` 11.09 µs/iter` | ` 10.99 µs` | ` 11.11 µs` | ` 11.13 µs` | ` 11.15 µs` || bigint large -> (1) | ` 11.06 µs/iter` | ` 10.99 µs` | ` 11.07 µs` | ` 11.10 µs` | ` 11.12 µs` || boolean true -> (1) | ` 11.09 µs/iter` | ` 11.02 µs` | ` 11.11 µs` | ` 11.14 µs` | ` 11.18 µs` || boolean false -> (1) | ` 11.07 µs/iter` | ` 11.02 µs` | ` 11.10 µs` | ` 11.10 µs` | ` 11.11 µs` || undefined -> (1) | ` 11.05 µs/iter` | ` 11.03 µs` | ` 11.05 µs` | ` 11.07 µs` | ` 11.09 µs` || null -> (1) | ` 11.09 µs/iter` | ` 11.03 µs` | ` 11.11 µs` | ` 11.13 µs` | ` 11.13 µs` || string -> (1) | ` 11.09 µs/iter` | ` 11.04 µs` | ` 11.12 µs` | ` 11.13 µs` | ` 11.15 µs` || json object -> (1) | ` 14.88 µs/iter` | ` 14.63 µs` | ` 14.86 µs` | ` 14.93 µs` | ` 15.82 µs` || json array -> (1) | ` 18.70 µs/iter` | ` 18.45 µs` | ` 18.65 µs` | ` 18.79 µs` | ` 19.73 µs` || Uint8Array -> (1) | ` 12.09 µs/iter` | ` 11.91 µs` | ` 12.13 µs` | ` 12.19 µs` | ` 12.35 µs` || ArrayBuffer -> (1) | ` 11.85 µs/iter` | ` 11.67 µs` | ` 11.90 µs` | ` 12.00 µs` | ` 12.10 µs` || Buffer -> (1) | ` 14.02 µs/iter` | ` 13.70 µs` | ` 14.18 µs` | ` 14.21 µs` | ` 14.29 µs` || string huge -> (1) | ` 11.23 µs/iter` | ` 11.17 µs` | ` 11.27 µs` | ` 11.34 µs` | ` 11.34 µs` || Int32Array -> (1) | ` 12.08 µs/iter` | ` 11.94 µs` | ` 12.11 µs` | ` 12.31 µs` | ` 12.34 µs` || Float64Array -> (1) | ` 12.12 µs/iter` | ` 11.99 µs` | ` 12.21 µs` | ` 12.25 µs` | ` 12.30 µs` || BigInt64Array -> (1) | ` 12.11 µs/iter` | ` 11.91 µs` | ` 12.17 µs` | ` 12.33 µs` | ` 12.41 µs` || BigUint64Array -> (1) | ` 12.10 µs/iter` | ` 11.95 µs` | ` 12.18 µs` | ` 12.23 µs` | ` 12.29 µs` || DataView -> (1) | ` 12.67 µs/iter` | ` 12.02 µs` | ` 13.01 µs` | ` 13.15 µs` | ` 13.17 µs` || Date -> (1) | ` 11.41 µs/iter` | ` 5.92 µs` | ` 12.00 µs` | ` 32.67 µs` | `168.46 µs` |
| • worker 100 | avg | min | p75 | p99 | max || ----------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || number -> (100) | `173.42 µs/iter` | `121.71 µs` | `177.04 µs` | `333.04 µs` | ` 3.54 ms` || bigint small -> (100) | `178.73 µs/iter` | `122.33 µs` | `183.04 µs` | `333.79 µs` | ` 3.50 ms` || bigint large -> (100) | `171.77 µs/iter` | `123.63 µs` | `175.42 µs` | `325.08 µs` | ` 3.16 ms` || boolean true -> (100) | `168.30 µs/iter` | `119.96 µs` | `172.38 µs` | `321.25 µs` | ` 3.08 ms` || boolean false -> (100) | `168.24 µs/iter` | `119.42 µs` | `171.92 µs` | `327.38 µs` | ` 3.18 ms` || undefined -> (100) | `174.87 µs/iter` | `122.58 µs` | `180.38 µs` | `324.38 µs` | ` 3.31 ms` || null -> (100) | `177.45 µs/iter` | `122.75 µs` | `183.29 µs` | `318.17 µs` | ` 3.12 ms` || string -> (100) | `172.13 µs/iter` | `121.83 µs` | `175.33 µs` | `311.46 µs` | ` 3.44 ms` || json object -> (100) | `349.71 µs/iter` | `272.13 µs` | `358.25 µs` | `539.25 µs` | ` 3.52 ms` || json array -> (100) | `518.73 µs/iter` | `409.38 µs` | `542.92 µs` | `754.54 µs` | ` 3.59 ms` || Uint8Array -> (100) | `242.72 µs/iter` | `171.54 µs` | `253.50 µs` | `506.21 µs` | ` 2.42 ms` || ArrayBuffer -> (100) | `229.70 µs/iter` | `160.50 µs` | `239.67 µs` | `470.63 µs` | ` 2.41 ms` || Buffer -> (100) | `354.02 µs/iter` | `222.83 µs` | `376.63 µs` | `974.71 µs` | ` 1.47 ms` || string huge -> (100) | `197.79 µs/iter` | `141.29 µs` | `197.08 µs` | `371.71 µs` | ` 2.56 ms` || Int32Array -> (100) | `243.54 µs/iter` | `169.13 µs` | `254.42 µs` | `512.29 µs` | ` 2.56 ms` || Float64Array -> (100) | `243.76 µs/iter` | `170.29 µs` | `254.00 µs` | `541.63 µs` | ` 2.44 ms` || BigInt64Array -> (100) | `242.08 µs/iter` | `170.46 µs` | `252.08 µs` | `527.83 µs` | ` 2.48 ms` || BigUint64Array -> (100) | `241.30 µs/iter` | `168.63 µs` | `253.17 µs` | `481.75 µs` | ` 2.53 ms` || DataView -> (100) | `240.07 µs/iter` | `169.00 µs` | `250.58 µs` | `529.42 µs` | ` 2.49 ms` || Date -> (100) | `174.26 µs/iter` | `124.38 µs` | `178.88 µs` | `325.83 µs` | ` 3.36 ms` |Call growth throughput (Node)
Section titled “Call growth throughput (Node)”This benchmark increases payload size from 32 B up to 1,048,576 B (1 MiB) and reports
the time per batch with batch=64.
Using the 1048576 B row (avg) from the batch=64 run, one-way transfer throughput is:
string:46.54 ms/iter->1.44 GB/sUint8Array:8.95 ms/iter->7.50 GB/s
Interpretation:
- In this batch test, Node transfers
Uint8Arraypayloads much faster than strings. - For 1 MiB binary payloads, Node lands in the
~7.5 GB/srange in this run.
clk: ~3.70 GHzcpu: Apple M3 Ultraruntime: node 24.12.0 (arm64-darwin)
| • call growth batch string (ascii 32..1048576 x4, batch=64) | avg | min | p75 | p99 | max || --------- | ---------------- | ----------- | ----------- | ----------- | ----------- || 32 B | ` 22.96 µs/iter` | ` 14.58 µs` | ` 28.71 µs` | ` 54.04 µs` | `582.58 µs` || 128 B | ` 27.04 µs/iter` | ` 24.48 µs` | ` 27.65 µs` | ` 28.63 µs` | ` 28.94 µs` || 512 B | ` 44.43 µs/iter` | ` 40.30 µs` | ` 46.17 µs` | ` 46.61 µs` | ` 48.79 µs` || 2048 B | `142.37 µs/iter` | `103.71 µs` | `168.75 µs` | `233.46 µs` | `301.04 µs` || 8192 B | `399.94 µs/iter` | `339.63 µs` | `418.25 µs` | `513.25 µs` | ` 1.59 ms` || 32768 B | ` 1.40 ms/iter` | ` 1.28 ms` | ` 1.43 ms` | ` 2.43 ms` | ` 2.56 ms` || 131072 B | ` 7.07 ms/iter` | ` 5.41 ms` | ` 7.39 ms` | ` 11.23 ms` | ` 11.49 ms` || 524288 B | ` 23.22 ms/iter` | ` 21.87 ms` | ` 23.57 ms` | ` 24.56 ms` | ` 25.24 ms` || 1048576 B | ` 46.54 ms/iter` | ` 44.57 ms` | ` 47.59 ms` | ` 47.69 ms` | ` 48.34 ms` |
| • call growth batch uint8array (32..1048576 x4, batch=64) | avg | min | p75 | p99 | max || --------- | ---------------- | ----------- | ----------- | ----------- | ----------- || 32 B | ` 25.21 µs/iter` | ` 15.46 µs` | ` 29.63 µs` | ` 55.04 µs` | `462.75 µs` || 128 B | ` 26.11 µs/iter` | ` 23.47 µs` | ` 25.99 µs` | ` 30.16 µs` | ` 33.14 µs` || 512 B | ` 26.26 µs/iter` | ` 24.79 µs` | ` 26.35 µs` | ` 26.92 µs` | ` 32.01 µs` || 2048 B | ` 81.17 µs/iter` | ` 41.04 µs` | ` 97.46 µs` | `178.63 µs` | ` 4.42 ms` || 8192 B | `181.59 µs/iter` | ` 91.17 µs` | `190.71 µs` | ` 1.10 ms` | ` 3.30 ms` || 32768 B | `431.63 µs/iter` | `178.17 µs` | `370.88 µs` | ` 2.35 ms` | ` 3.21 ms` || 131072 B | ` 1.40 ms/iter` | `777.21 µs` | ` 1.72 ms` | ` 3.20 ms` | ` 3.36 ms` || 524288 B | ` 4.66 ms/iter` | ` 3.53 ms` | ` 5.08 ms` | ` 6.42 ms` | ` 7.07 ms` || 1048576 B | ` 8.95 ms/iter` | ` 7.54 ms` | ` 9.32 ms` | ` 11.37 ms` | ` 12.30 ms` |Efficiency under heavy tasks (Node)
Section titled “Efficiency under heavy tasks (Node)”This stress test computes prime numbers over a large range, then serializes and parses large JSON payloads:
const N = 10_000_000; // search range: [1..N]const CHUNK_SIZE = 250_000;Even under this heavier workload, parallel workers scale well:
main + 1 extra thread:~1.7xfaster than main only.main + 2 extra threads:~2.3xfaster than main only.main + 3 extra threads:~3.0xfaster than main only.main + 4 extra threads:~3.5xfaster than main only.
clk: ~3.72 GHzcpu: Apple M3 Ultraruntime: node 24.12.0 (arm64-darwin)
| • knitting: primes up to 10,000,000 (chunk=250,000) | avg | min | p75 | p99 | max || ----------------------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || main | `959.14 ms/iter` | `955.16 ms` | `959.93 ms` | `961.89 ms` | `963.68 ms` || main + 1 extra threads → full range | `538.28 ms/iter` | `531.37 ms` | `539.87 ms` | `541.65 ms` | `547.02 ms` || main + 2 extra threads → full range | `401.87 ms/iter` | `395.43 ms` | `404.32 ms` | `406.77 ms` | `408.40 ms` || main + 3 extra threads → full range | `317.52 ms/iter` | `311.27 ms` | `319.14 ms` | `323.94 ms` | `327.36 ms` || main + 4 extra threads → full range | `274.21 ms/iter` | `270.63 ms` | `276.88 ms` | `278.30 ms` | `279.69 ms` |All types in Knitting
Section titled “All types in Knitting”This benchmark covers primitives, structured values, collections, typed arrays,
errors, dates, symbols, and promise arguments. It also compares static and
dynamic payload allocation.
Results are reported for count 1 and count 100 to show both per-call latency and batched throughput.
Quick takeaways:
- At count
100, primitive payloads are usually in the~15-30 µsrange, while heavier structured/collection payloads can be~120-300+ µs. - The static payload path is usually around
2x-4xfaster than dynamic allocator paths (for example: string~3.4x, JSON~3.0x,Uint8Array~3.6x, symbol~4.1xat count100).
Payload sizes (approximate):
| Payload | Size |
|---|---|
jsonObj | 206 B |
jsonArr | 217 B |
mapPayload | 284 B |
Uint8Array | 1024 B |
Int32Array | 1024 B |
Float64Array | 1024 B |
BigInt64Array | 1024 B |
BigUint64Array | 1024 B |
DataView | 1024 B |
smallU8 | 480 B |
largeU8 | 481 B |
payload sizes (approx bytes): jsonObj: 206 bytes jsonArr: 217 bytes stringHuge: 1024 bytes Uint8Array: 1024 bytes Int32Array: 1024 bytes Float64Array: 1024 bytes BigInt64Array: 1024 bytes BigUint64Array: 1024 bytes DataView: 1024 bytes
clk: ~3.73 GHzcpu: Apple M3 Ultraruntime: node 24.12.0 (arm64-darwin)
| • knitting-types 1 | avg | min | p75 | p99 | max || --------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || number -> (1) | ` 1.16 µs/iter` | `458.00 ns` | ` 1.54 µs` | ` 2.75 µs` | ` 1.63 ms` || bigint small -> (1) | ` 1.05 µs/iter` | `500.00 ns` | ` 1.50 µs` | ` 2.17 µs` | ` 1.26 ms` || bigint large -> (1) | ` 2.48 µs/iter` | ` 1.25 µs` | ` 2.54 µs` | ` 5.58 µs` | ` 4.13 ms` || boolean true -> (1) | `901.13 ns/iter` | `526.34 ns` | ` 1.21 µs` | ` 1.58 µs` | ` 1.60 µs` || boolean false -> (1) | `824.29 ns/iter` | `520.36 ns` | ` 1.03 µs` | ` 1.57 µs` | ` 1.65 µs` || undefined -> (1) | `984.18 ns/iter` | `526.26 ns` | ` 1.32 µs` | ` 1.58 µs` | ` 1.62 µs` || null -> (1) | `847.02 ns/iter` | `525.11 ns` | ` 1.12 µs` | ` 1.57 µs` | ` 1.57 µs` || string -> (1) | ` 1.44 µs/iter` | `583.00 ns` | ` 2.08 µs` | ` 2.75 µs` | ` 1.24 ms` || json object -> (1) | ` 3.47 µs/iter` | ` 2.46 µs` | ` 3.83 µs` | ` 8.04 µs` | ` 1.27 ms` || json array -> (1) | ` 4.65 µs/iter` | ` 3.42 µs` | ` 4.96 µs` | ` 9.92 µs` | ` 1.24 ms` || Uint8Array -> (1) | ` 2.83 µs/iter` | ` 1.13 µs` | ` 3.42 µs` | ` 7.25 µs` | ` 1.28 ms` || ArrayBuffer -> (1) | ` 2.89 µs/iter` | ` 1.42 µs` | ` 3.71 µs` | ` 7.88 µs` | ` 1.31 ms` || Buffer -> (1) | ` 2.54 µs/iter` | ` 1.73 µs` | ` 2.95 µs` | ` 3.55 µs` | ` 3.57 µs` || string huge -> (1) | ` 3.24 µs/iter` | ` 1.92 µs` | ` 4.00 µs` | ` 7.50 µs` | ` 1.24 ms` || Int32Array -> (1) | ` 2.64 µs/iter` | ` 1.13 µs` | ` 3.33 µs` | ` 6.42 µs` | ` 1.27 ms` || Float64Array -> (1) | ` 2.76 µs/iter` | ` 1.38 µs` | ` 3.63 µs` | ` 7.42 µs` | ` 1.43 ms` || BigInt64Array -> (1) | ` 2.53 µs/iter` | ` 1.13 µs` | ` 3.25 µs` | ` 6.25 µs` | ` 1.27 ms` || BigUint64Array -> (1) | ` 2.58 µs/iter` | ` 1.17 µs` | ` 3.29 µs` | ` 6.29 µs` | ` 1.28 ms` || DataView -> (1) | ` 2.70 µs/iter` | ` 1.80 µs` | ` 3.08 µs` | ` 3.53 µs` | ` 3.57 µs` || Date -> (1) | ` 1.10 µs/iter` | `687.13 ns` | ` 1.37 µs` | ` 1.87 µs` | ` 1.96 µs` || Symbol.for -> (1) | ` 1.62 µs/iter` | ` 1.19 µs` | ` 1.84 µs` | ` 2.15 µs` | ` 2.24 µs` |
| • knitting-types 100 | avg | min | p75 | p99 | max || ----------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || number -> (100) | ` 25.45 µs/iter` | ` 15.33 µs` | ` 33.38 µs` | ` 62.25 µs` | ` 1.25 ms` || bigint small -> (100) | ` 27.62 µs/iter` | ` 25.17 µs` | ` 29.19 µs` | ` 30.32 µs` | ` 32.61 µs` || bigint large -> (100) | ` 70.42 µs/iter` | ` 53.38 µs` | ` 73.75 µs` | `134.50 µs` | ` 1.44 ms` || boolean true -> (100) | ` 27.65 µs/iter` | ` 23.07 µs` | ` 29.43 µs` | ` 31.76 µs` | ` 32.41 µs` || boolean false -> (100) | ` 26.79 µs/iter` | ` 24.41 µs` | ` 27.28 µs` | ` 28.78 µs` | ` 29.58 µs` || undefined -> (100) | ` 26.81 µs/iter` | ` 24.37 µs` | ` 27.73 µs` | ` 29.37 µs` | ` 34.09 µs` || null -> (100) | ` 24.44 µs/iter` | ` 21.21 µs` | ` 25.08 µs` | ` 26.05 µs` | ` 28.83 µs` || string -> (100) | ` 35.29 µs/iter` | ` 31.39 µs` | ` 36.22 µs` | ` 38.08 µs` | ` 41.26 µs` || json object -> (100) | `123.26 µs/iter` | `105.54 µs` | `123.92 µs` | `221.92 µs` | ` 1.39 ms` || json array -> (100) | `178.94 µs/iter` | `154.96 µs` | `185.13 µs` | `285.50 µs` | `491.88 µs` || Uint8Array -> (100) | `108.25 µs/iter` | ` 56.88 µs` | `141.25 µs` | `215.38 µs` | ` 3.06 ms` || ArrayBuffer -> (100) | `123.32 µs/iter` | ` 66.17 µs` | `153.63 µs` | `230.04 µs` | ` 2.51 ms` || Buffer -> (100) | `102.49 µs/iter` | ` 57.42 µs` | `139.83 µs` | `215.08 µs` | ` 2.97 ms` || string huge -> (100) | `162.92 µs/iter` | `111.25 µs` | `210.12 µs` | `268.54 µs` | ` 1.44 ms` || Int32Array -> (100) | `103.37 µs/iter` | ` 58.38 µs` | `141.13 µs` | `212.63 µs` | ` 3.04 ms` || Float64Array -> (100) | `121.34 µs/iter` | ` 65.71 µs` | `147.25 µs` | `230.96 µs` | ` 1.85 ms` || BigInt64Array -> (100) | `105.26 µs/iter` | ` 58.75 µs` | `139.79 µs` | `207.92 µs` | ` 3.10 ms` || BigUint64Array -> (100) | `102.90 µs/iter` | ` 59.21 µs` | `140.08 µs` | `203.58 µs` | ` 3.23 ms` || DataView -> (100) | `110.45 µs/iter` | ` 61.42 µs` | `145.21 µs` | `217.79 µs` | ` 2.74 ms` || Date -> (100) | ` 32.51 µs/iter` | ` 29.91 µs` | ` 33.09 µs` | ` 34.62 µs` | ` 38.05 µs` || Symbol.for -> (100) | ` 40.59 µs/iter` | ` 38.45 µs` | ` 41.20 µs` | ` 41.93 µs` | ` 42.32 µs` |
| • knitting-promise-args 1 | avg | min | p75 | p99 | max || --------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || promise number -> (1) | ` 1.65 µs/iter` | ` 1.20 µs` | ` 1.83 µs` | ` 2.12 µs` | ` 2.15 µs` || promise object -> (1) | ` 2.69 µs/iter` | ` 2.20 µs` | ` 2.93 µs` | ` 3.15 µs` | ` 3.16 µs` |
| • knitting-promise-args 100 | avg | min | p75 | p99 | max || ----------------------- | ---------------- | ----------- | ----------- | ----------- | ----------- || promise number -> (100) | ` 33.41 µs/iter` | ` 30.85 µs` | ` 34.19 µs` | ` 37.45 µs` | ` 37.53 µs` || promise object -> (100) | ` 71.73 µs/iter` | ` 57.46 µs` | ` 77.17 µs` | `139.38 µs` | `253.00 µs` |