npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

fast-thread

v0.0.6

Published

Implementing cross-thread serialization using SharedArrayBuffer + Atomics

Downloads

10

Readme

🚀 fast-thread

fast-thread is a high-performance module designed for ultra-fast object transmission between threads in Node.js, optimizing parallel processing with SharedArrayBuffer, Atomics, and fast-json-stringify.

🔥 Why fast-thread?

In Node.js, thread communication has inherent limitations:

  • No native memory sharing like in other languages.
  • All data must be serialized and sent via messaging, adding overhead.
  • Complex objects cannot be shared natively, requiring costly serialization.

For high-performance applications, reducing serialization time directly improves parallel processing speed.

🚀 The Challenge: Finding the Fastest Serialization Method

We tested multiple serialization methods to find the fastest approach for inter-thread communication in Node.js.

| Serialization Method | Pros | Cons | |---------------------------|-------------------------------------------|---------------------------------------------| | JSON (JSON.stringify) | Built-in, no dependencies | Slower serialization, larger payload | | msgpack-lite | Compact binary format | Slower than JSON in V8 | | CBOR | Compact and structured binary format | Still slower than JSON | | BSON | Optimized for MongoDB, fast parsing | High overhead for small objects | | Protobuf.js | Compact, schema-based, high performance | Requires pre-defined schema | | fast-json-stringify | Faster than JSON.stringify with schema | Still requires copying in postMessage() | | fast-thread 🚀 | SharedArrayBuffer + Atomics (No Copy) | Requires structured memory handling |

After extensive benchmarking, the fastest approach was a combination of:

  • SharedArrayBuffer for direct memory access
  • Atomics.wait()/Atomics.notify() for ultra-fast synchronization
  • fast-json-stringify for zero-copy, schema-based serialization

📊 Benchmark Results

Our tests measured message throughput (msg/sec) and bandwidth (MB/sec) over a 10s test period.

| Name | Messages | Messages Per Second | MB Per Second | |--------------------------|----------|---------------------|--------------| | fast-thread | 617,483 | 61,748.30 | 65.34 | | JSON | 524,235 | 52,423.50 | 55.48 | | fast-json-stringify | 500,024 | 50,002.40 | 52.10 | | BSON | 420,946 | 42,094.60 | 44.19 | | Protobuf.js | 296,340 | 29,634.00 | 29.75 | | msgpack-lite | 288,180 | 28,818.00 | 29.86 | | CBOR | 223,945 | 22,394.50 | 23.20 |

🚀 fast-thread achieved the best performance with a throughput of ~61,748 messages per second and 65.34 MB/sec.


⚡ Solution: SharedArrayBuffer + Atomics + fast-json-stringify

How It Works

  • SharedArrayBuffer is used for zero-copy memory sharing.
  • Atomics.wait()/Atomics.notify() provide fast synchronization between threads.
  • fast-json-stringify eliminates JSON parsing overhead.

📌 Installation

pnpm install fast-thread

🛠 Example Usage

Worker Thread (worker_fast.js)

const { workerData } = require("worker_threads");
const fastJson = require("fast-json-stringify");
const { unpackObject, packObject } = require("fast-thread");

const sharedBuffer = workerData;
const stringify = fastJson({
    title: "Example",
    type: "object",
    properties: {
        id: { type: "integer" },
        name: { type: "string" },
        timestamp: { type: "integer" },
        data: { type: "string" }
    }
});

async function processData() {
    while (true) {
        Atomics.wait(sharedBuffer.signal, 0, 0);

        let obj = unpackObject(sharedBuffer);
        if (!obj) continue;

        obj.processed = true;
        packObject(stringify(obj), sharedBuffer, 1);
    }
}

processData();

Main Thread (test.js)

const { FastThread } = require("fast-thread");

(async () => {
    const fastThread = new FastThread("./worker_fast.js", 1024 * 1024)

    fastThread.on("message", (data) => {
        console.log("[Main] Processed data received:", data);
    });

    fastThread.on("terminated", () => {
        console.log("Thread closed");
    });

    for(let i = 0; i < 100; i++){
        fastThread.send({
            id: i,
            name: "User " + i,
            timestamp: Date.now(),
            data: "x".repeat(512)
        });

        await fastThread.awaitThreadReponse();
    }

    setTimeout(() => fastThread.terminate(), 2000);
})();

Since SharedArrayBuffer has a fixed size, it's essential to send messages sequentially, waiting for a response before sending the next job. This prevents buffer overwriting, ensuring each message is processed correctly.

Currently, no parallel message handling system has been implemented, meaning multiple messages cannot be processed simultaneously within the same thread instance.

To handle this limitation, the await fastThread.awaitThreadResponse(); call ensures that each message is processed before sending the next one. Without this mechanism, sending multiple messages at once could result in data loss or overwritten responses.

Main Thread (test-alternative.js)

const { Worker } = require("worker_threads");
const fastJson = require("fast-json-stringify");

const { 
    createSharedBuffer, packObject, 
    unpackObject 
} = require("fast-thread");

const sharedBuffer = createSharedBuffer();
const worker = new Worker("./worker_fast.js", { workerData: sharedBuffer });

const stringify = fastJson({
    title: "Example",
    type: "object",
    properties: {
        id: { type: "integer" },
        name: { type: "string" },
        timestamp: { type: "integer" },
        data: { type: "string" }
    }
});

packObject(stringify({ 
    id: 1, 
    name: "User A", 
    timestamp: Date.now(), 
    data: "x".repeat(512) 
}), sharedBuffer);

const checkResponses = () => {
    Atomics.wait(sharedBuffer.signal, 1, 0);
    const processedData = unpackObject(sharedBuffer, 1);
    console.log("[Main] Processed data received:", processedData);
    setImmediate(checkResponses);
};

📌 Conclusion

fast-thread enables blazing-fast thread communication in Node.js using SharedArrayBuffer, Atomics, and fast-json-stringify. This approach eliminates message serialization overhead, delivering unparalleled performance in high-throughput parallel workloads.