Live data from Hacker News

Node.js worker threads are problematic, but they work great for us

inngest.com

21–30 of 35 posts

Re: Node.js worker threads are problematic, but they work great for us

#21
post #7

Reading the article, I didn’t see this answered: why not scale to more nodes if your workload is CPU bound? Spin off 1 cpu and a few gb of ram container and scale that as wide as you need? e.g., this certainly helps when the event loop is blocked, but so could FFI calls to another language for the CPU bound work. I’d only reach for a new Node thread if these didn’t pan out, because there’s usually a LOT that goes int…

> few gb of ram ...

5 years ago I never would have given this comment a second thought.

Now I read it and have to wonder: when does the price of ram start showing up in the butchers bill from your cloud provider?

Re: Node.js worker threads are problematic, but they work great for us

#22
post #7

Reading the article, I didn’t see this answered: why not scale to more nodes if your workload is CPU bound? Spin off 1 cpu and a few gb of ram container and scale that as wide as you need? e.g., this certainly helps when the event loop is blocked, but so could FFI calls to another language for the CPU bound work. I’d only reach for a new Node thread if these didn’t pan out, because there’s usually a LOT that goes int…

> few gb of ram ... 5 years ago I never would have given this comment a second thought. Now I read it and have to wonder: when does the price of ram start showing up in the butchers bill from your cloud provider?

I don't know about you, but my cloud provider has been charging me for the ram on my compute instances since the beginning.

Re: Node.js worker threads are problematic, but they work great for us

#23
post #14

The article calls worker threads "problematic", but it doesn’t really make a strong case for why they’re supposedly problematic. Having a separate isolate in each threads spawned with the worker threads with a minimal footprint of 10MB does not seem like a high price to pay. It's not like you're going to spawn hundreds of them anyway is it? You will very likely spawn less or as much threads as your CPU cores can hand…

The problematic part is mostly in nomenclature. They’re called “threads” but don’t really behave the way you’d expect threads to. They’re heavy, they don’t share the entire process memory space (ie can’t reference functions), and I believe their imports are separate from each other (ie reparsed for each worker into its own memory space). In many ways they’re closer to subprocesses in other languages, with limited sha…

If it’s any comfort, I don’t hear many JS/TS/Node/etc developers calling them threads or really thinking of them that way. Usually just Workers or Web Workers — "worker threads" mostly slips in from Node. Even then, "worker" dominates.

In terms of tradeoffs, if you’re coming from the single event loop model, they’re pretty consistent with the rest of JS. Isolation-first, explicit sharing, fewer footguns. So I think the tradeoffs are the right tradeoffs.

FWIW, traditional threads have their own tradeoffs (especially around IO). In JS that’s mostly a non-issue, so the "I need 1000s of threads" case just doesn’t come up very often.

Re: Node.js worker threads are problematic, but they work great for us

#25

Earlier quoted context omitted.

> few gb of ram ... 5 years ago I never would have given this comment a second thought. Now I read it and have to wonder: when does the price of ram start showing up in the butchers bill from your cloud provider?

I don't know about you, but my cloud provider has been charging me for the ram on my compute instances since the beginning.

Ram has always been one of the major price drivers...

But the prices have gotten stupid: https://pcpartpicker.com/trends/price/memory/

https://appleinsider.com/articles/26/02/27/the-global-ram-an...

Re: Node.js worker threads are problematic, but they work great for us

#26
post #14

The article calls worker threads "problematic", but it doesn’t really make a strong case for why they’re supposedly problematic. Having a separate isolate in each threads spawned with the worker threads with a minimal footprint of 10MB does not seem like a high price to pay. It's not like you're going to spawn hundreds of them anyway is it? You will very likely spawn less or as much threads as your CPU cores can hand…

The problematic part is mostly in nomenclature. They’re called “threads” but don’t really behave the way you’d expect threads to. They’re heavy, they don’t share the entire process memory space (ie can’t reference functions), and I believe their imports are separate from each other (ie reparsed for each worker into its own memory space). In many ways they’re closer to subprocesses in other languages, with limited sha…

I think the isolation and memory safety guarantees that worker threads (or Web Workers) provide are very welcome. The friction mainly comes from ergonomics, as pointed out in the article. So there’s definitely room for improvement there (even within the current constraints).

A worker thread or Web Worker runs in its own isolate, so it needs to initialise it by parsing and executing its entry point. I'm not quite sure whether that's something that already happens but you could imagine optimising this by caching or snapshotting the initial state of an isolate when multiple workers use the same entry point, so new workers can start faster.

That cannot be done with the original main thread isolate because usually the worker environment has both different capabilities than the main isolate and a different entry point.

If I have to handle 1000 files in a small CLI I would probably just use Node.js asynchronous IO in a single thread and let it handle platform specifics for me! You’ll get very good throughput without having to handle threads yourself.

Re: Node.js worker threads are problematic, but they work great for us

#27
post #16

The worker situation would be much better with inline workers (or modules). https://github.com/tc39/proposal-module-declarations Unfortunately the JS standards folks have refused so far to make this situation better. Ex. it should just be `new Worker(module { ... })`.

We haven't refused, it just takes time! There was an update at the meeting two weeks ago [1]. There's a lot of other machinery which needs to be specified and implemented before module declarations will work but it's coming along.

[1] https://docs.google.com/presentation/d/1inTcnb4hugyAvKrjFX_X...

Re: Node.js worker threads are problematic, but they work great for us

#28
post #14

The article calls worker threads "problematic", but it doesn’t really make a strong case for why they’re supposedly problematic. Having a separate isolate in each threads spawned with the worker threads with a minimal footprint of 10MB does not seem like a high price to pay. It's not like you're going to spawn hundreds of them anyway is it? You will very likely spawn less or as much threads as your CPU cores can hand…

The problematic part is mostly in nomenclature. They’re called “threads” but don’t really behave the way you’d expect threads to. They’re heavy, they don’t share the entire process memory space (ie can’t reference functions), and I believe their imports are separate from each other (ie reparsed for each worker into its own memory space). In many ways they’re closer to subprocesses in other languages, with limited sha…

No, they're threads as far as the OS is concerned (they'll map to OS threads) and actually _do_ share physical process and memory (that's how SharedArrayBuffer works).

However, apart from atomic "plain" memory no objects are directly shared (For Node/V8 they live in so called Isolated iirc) so from a logical standpoint they're kinda like a process.

The underlying reason is that in JavaScript objects are by default open to modification, ie:

  const t = {x:1,y:2};
  t.z = 3;
  console.log(t); // => { x: 1, y: 2, z: 3 }
To get sane performance out of JS there are a ton of tricks the runtime does under the hood, the bad news is that those are all either slow (think Python GIL) or heavily exploitable in a multithreaded scenario.

If you've done multithreaded C/C++ work and touched upon Erlang the JS Worker design is the logical conclusion, message passing works for small packets (work orders, structured cloning) whilst large data-shipping can be problematic with cloning.

This is why SharedArrayBuffer:s allows for no-copy sharing since the plain memory arrays they expose don't offer any security surprises in terms of code execution (spectre style attacks is another story) and also allows for work-subdivision if needed.

Re: Node.js worker threads are problematic, but they work great for us

#29
post #16

The worker situation would be much better with inline workers (or modules). https://github.com/tc39/proposal-module-declarations Unfortunately the JS standards folks have refused so far to make this situation better. Ex. it should just be `new Worker(module { ... })`.

It's all about security, see my other comment. https://news.ycombinator.com/item?id=47480080

Re: Node.js worker threads are problematic, but they work great for us

#30
post #7

Reading the article, I didn’t see this answered: why not scale to more nodes if your workload is CPU bound? Spin off 1 cpu and a few gb of ram container and scale that as wide as you need? e.g., this certainly helps when the event loop is blocked, but so could FFI calls to another language for the CPU bound work. I’d only reach for a new Node thread if these didn’t pan out, because there’s usually a LOT that goes int…

> few gb of ram ... 5 years ago I never would have given this comment a second thought. Now I read it and have to wonder: when does the price of ram start showing up in the butchers bill from your cloud provider?

You have to pay that cost in a worker thread anyway, too. There’s no free lunch.
Post reply on HN