- Erlang/Elixir (from now on I will just say Elixir) have parallelism out of the box. Node.js is a single threaded event loop so you only get CPU parallelism by forking.
- Elixir is also massively concurrent and has non blocking IO but instead of using callbacks/promises you just write your code sequentially and the BEAM (Elixir's VM) takes care of scheduling for you.
- In benchmarks, Elixir maintains a very consistent 99th percentile whereas Node's 99th percentile latency drastically gets worse as the active number of connections increase.
Which, minus the IPC, code/dependency sharing, has similar practical consequences as Erlang/Elixir: no shared heap.
> but instead of using callbacks/promises
At a level as high as JavaScript this doesn't matter, but, green threads are not as performant as this model would be in a lower-level language.
Edge-triggered, multi-threaded event loops + callbacks are a force to be reckoned with on the concurrency front.
> 99th percentile latency
Single-core tests? For both Erlang (BEAM) and Node.js?
I'd like to see this testing and the reasoning behind it, though if true, I suspect it's probably related to GC latency (and the high cost of JS execution contexts).
In Elixir/Erlang every Erlang process has its own heap. In the case of Node.js and forking, each forked process has its own heap. You can't fork 100,000 times but you can have 100,000+ Erlang processes all with separate heaps and all in the same process.
Elixir (because Erlang) handles the distributing of 'processes' (not operating system processes but Erlang lightweight process) across cores for you. Erlang's been doing concurrency for a long time, it's very good at it.
The style of programming is very different in that you are encouraged to use processes in Elixir, rather than the callback style that is prevalent in Node. It feels weird at first, but pretty natural after a while.
I'm not sure there's much you can do in Node that you can't do in Elixir. But there are features in Elixir (again, because Erlang) like hot-code-reloading (update your app whilst it is running), and the way it can distribute tasks across nodes that I'm not sure are that straight-forward with Node.