Erlang/Elixir's multi core story?

What is the correct way to run Erlang/Elixir on a mujlt icore machine ?

  1. run one VM per core, connect them via distributed Erlang

  2. run one VM per physical machine, the VM automatically utilizes all cores ?

1 Like

I’d go with 2, unless there’s a specific reason not to. The Erlang VM is designed to utilise multiple cores. See comment 3 on this thread: Doex Elixir handle multiple core utilization automatically? - #3 by rvirding - from one of the creators of Erlang.


This is fantastic and authoritative. However, for the sake of convincing others, is this stated anywhere in the official Erlang documentation ?

8.3 SMP Emulator

The SMP emulator (introduced in R11B) takes advantage of a multi-core or multi-CPU computer by running several Erlang scheduler threads (typically, the same as the number of cores). Each scheduler thread schedules Erlang processes in the same way as the Erlang scheduler in the non-SMP emulator.

To gain performance by using the SMP emulator, your application must have more than one runnable Erlang process most of the time. Otherwise, the Erlang emulator can still only run one Erlang process at the time, but you must still pay the overhead for locking. Although Erlang/OTP tries to reduce the locking overhead as much as possible, it will never become exactly zero.

Source: Erlang -- Processes


Thank you @sfusato , this basically answers my question, with one potential caveat. Sorry to be pedantic, but what does ‘emulator’ mean here in this context? In other contexts, qemu/virtualbox, there is some performance hit vs x86 native. What does ‘emulator’ mean here in the Erlang context?

1 Like

Erlang virtual machine that emulates hypothetical “BEAM CPU”.

As others pointed out, you definitely want to run just one Erlang VM per machine and let it utilise all the cores.

An interesting question is what if your machine is virtualised and you can tune the physical machine to run, say, 8 containers. Should you then effectively start 8 Erlang VMs? No! Definitely let the Erlang VM utilise all available resources. :slight_smile:


What made me migrate to Elixir 5 years ago was Task.async_stream. You fetch stuff from files / DB / network / etc. and feed them to this function and it just automatically multiplexes calls to the supplied function to all available CPU cores in a batching manner.

Say you have 100 tasks and a 8-core machine, so using Task.async_stream would immediately start executing tasks 0 to 7 and then just fill up any freed slots with the next tasks until all of them are exhausted.

Just an anecdote. I came to Elixir looking for ways to use all CPU cores without writing hundreds of coding lines first, and that’s exactly what I found.

I stopped caring about language syntax a while ago and I am only looking for the compiler / runtime goodies (with some exceptions; I dislike Java’s and Golang’s verbosiveness, and even if I love Rust it can be verbosive and whiny to the point of boiling my blood – for a really good cause though, so I am not really complaining).

The BEAM VM has amazing runtime goodies. If not for the BEAM VM then Erlang / Elixir would only be fringe languages of moderate curiosity.

  1. run one VM per physical machine, the VM automatically utilizes all cores ?
  • Unless you’re distributing globally or regionally across many machines and your workload may grow in which case you may want microservices / Kubernetes

Yes :slight_smile: I’ve heard José highlight this as part of the equation of building Elixir.

1 Like