And if it isn't non-blocking? What if I'm writing a game and want to run parts of the rendering, AI, physics, etc. in parallel? Do I create a bunch of containers for each subsystem of my game and have them all communicate via IPC? This doesn't sound like a recipe for good memory/performance characteristics.
But we’re talking about javascript here, a language that is async about almost everything.
I completely agree with what you’re saying for those other problems you describe. But for the typical node.js webapp, doing the one-container-per-core is perfectly fine.
A thread is just a process that shares memory; a container is just a process that has a different network/filesystem/etc than the rest of the processes.
Containers don't cost meaningfully more than threads unless you create expensive unique resources for each one.
Network/Filesystem/Memory are not expensive resources? It's a lot of overhead. If you're going to claim that you can share memory between containers than arguably you don't have multiple containers but rather a single one.
This is way more overhead than threads which can share all of those resources.
Network namespaces, virtual ethernet interfaces, iptables rules, & union filesystems are all very cheap and have little to no overhead for normal use cases. N processes in 1 container isn't a perf win over N processes in N containers.
Shared process memory isn't the easy memory-consumption win it sounds like, locking is hard to get right, potentially very destructive to the parallel performance that was the point of the whole exercise, and marries you to a single physical box.
Even if you want to take advantage of shared-address-space shared memory you probably want to do it in a more principled way than fork()
One-copy-per-thread and share-by-communicating both give you braindead simple scaling without dealing with that.