BEAM (Erlang VM)
By Ericsson / Erlang/OTP community
BEAM is the virtual machine that executes compiled bytecode for the Erlang programming language and, since its rise in popularity, the Elixir language as well. It is built around lightweight, isolated processes and preemptive scheduling…
Definition
BEAM is the virtual machine that executes compiled bytecode for the Erlang programming language and, since its rise in popularity, the Elixir language as well. It is built around lightweight, isolated processes and preemptive scheduling designed for highly concurrent, fault-tolerant, distributed systems, making it the runtime foundation of telecom switches, messaging platforms, and other systems that must stay available continuously.
Overview
BEAM was designed for a specific and demanding requirement: telecom switching systems that could not go down, needed to handle enormous numbers of simultaneous connections, and had to keep running while individual components failed and recovered. Rather than relying on operating-system threads and shared memory the way most runtimes of its era did, BEAM was built around a model where a program is composed of huge numbers of small, independent processes that communicate only by sending messages, never by sharing mutable state directly. Mechanically, each BEAM process has its own small, independently garbage-collected heap, its own stack, and a mailbox for incoming messages, and creating one is deliberately cheap, often costing only a few hundred bytes, so a single machine can run millions of them. BEAM's scheduler runs multiple operating-system threads, each cycling through many lightweight processes and preemptively switching between them based on reduction counts rather than waiting for a process to yield voluntarily, which prevents any single runaway process from starving the others. Because each process's memory is isolated, a crash in one process cannot corrupt another's state, and BEAM's supervision trees, a core Erlang/OTP pattern, let a supervisor process detect a crashed child and restart it automatically, which is the mechanical basis for Erlang's famous fault-tolerance. BEAM's process-and-message-passing concurrency model sets it apart from mainstream runtimes like the JVM or CPython, which rely on OS threads and, in Python's case, a global interpreter lock that limits true parallelism; BEAM instead achieves both massive concurrency and real fault isolation as first-class runtime features rather than library additions. It differs from Go's goroutine model, which is also lightweight and message-oriented via channels, mainly in maturity and philosophy: BEAM's supervision-tree approach to fault tolerance and its "let it crash" error-handling culture are deeply embedded in the runtime and standard library (OTP), whereas Go treats concurrency primitives more as building blocks without a prescribed fault-recovery pattern. In practice, BEAM underlies systems that must stay available with minimal downtime: telecom infrastructure, messaging platforms like WhatsApp's original backend, real-time systems built with the Elixir web framework Phoenix, and distributed databases and job queues that lean on OTP's process supervision. Hot code loading, replacing running code without stopping the system, is another BEAM capability exploited in systems that cannot tolerate scheduled downtime for deploys. The trade-off is raw single-threaded numeric performance: BEAM is not designed to be the fastest runtime for CPU-bound number crunching, and heavy numerical workloads are often delegated to native code via NIFs (natively implemented functions) or ports rather than run directly on BEAM processes. Teams choose BEAM for concurrency, fault tolerance, and uptime guarantees, not for competing with native code on tight numeric loops.
Key Features
- Runs millions of lightweight, isolated processes with independent heaps
- Preemptively schedules processes by reduction count, preventing starvation
- Isolates process memory so a crash cannot corrupt other processes' state
- Supports supervision trees for automatic detection and restart of failed processes
- Enables hot code loading to update running systems without downtime
- Executes both Erlang and Elixir compiled bytecode on the same runtime
- Uses message passing rather than shared memory for inter-process communication
- Scales concurrency across multiple CPU cores via its scheduler