So when does moving work onto a worker thread actually make things faster, and when does it quietly make them slower?
Good candidates price the offload first, serialization, scheduling, the clone back, and they know SharedArrayBuffer and Atomics are the escape hatch.
They help when the work is CPU-bound. So heavy parsing, compression, image manipulation, cryptography, that kind of thing, because those block the event loop and a worker gets them off the main thread. They don't help with I/O-bound work, Node already handles that asynchronously. And they can actually hurt when the tasks are small, because spawning threads and passing messages has overhead, which is why everyone uses a pool that reuses workers. The rule of thumb I've seen is that the computation should be big enough to outweigh the cost of sending the data over and getting the result back. Then SharedArrayBuffer lets threads share memory instead of copying it, and Atomics gives you safe reads and writes and waiting on that shared memory. That's how you avoid races when multiple threads are touching the same buffer.