Skip to content
Back to Blog
Engineering

What Is the BEAM and OTP? Elixir's Concurrency Model Explained

The BEAM and OTP are why Elixir handles massive concurrency and self-heals from failure. Here is how processes, schedulers, GenServer, and supervision trees actually work.

13 min read
Equantra

What Is the BEAM?

The BEAM is the virtual machine that runs Erlang and Elixir. It was built at Ericsson to run telephone switches that must never go down, and that heritage shapes everything about it: massive concurrency, fault isolation, soft real-time latency, and hot code upgrades. When people say Elixir “scales” and “self-heals,” they are really talking about the BEAM.

In one sentence: The BEAM runs millions of tiny, isolated processes that share nothing and talk only by messages, and OTP is the battle-tested library of patterns (GenServer, supervisors) for wiring those processes into reliable systems.

Lightweight Processes, Not OS Threads

A BEAM process is not an OS process or thread. It is an extremely cheap unit of concurrency—roughly 2 KB of memory—so a single machine can run millions of them at once. Each process has its own heap, so garbage collection happens per-process and never pauses the whole system.

Processes share no memory. They communicate by sending immutable messages to each other’s mailboxes. This “shared-nothing” design is what makes concurrency on the BEAM safe by default—there are no data races to guard against with locks.

# Spawn a process and send it a message
pid = spawn(fn ->
  receive do
    {:hello, from} -> send(from, :hi_back)
  end
end)

send(pid, {:hello, self()})

Preemptive Schedulers

The BEAM runs one scheduler per CPU core and multiplexes all those processes across them. Crucially, scheduling is preemptive: the VM interrupts a process after a small amount of work (reductions) so no single process can hog a core and starve the others. That is why BEAM systems keep low, predictable latency even under heavy load—the property that matters most for real-time apps.

What Is OTP?

OTP (Open Telecom Platform) is the set of libraries and design principles that turn raw processes into dependable systems. You rarely spawn bare processes in production Elixir—you use OTP abstractions, chiefly GenServer and supervisors.

GenServer: A Stateful Process With a Contract

A GenServer is a process that holds state and responds to synchronous calls and asynchronous casts through a standard set of callbacks. It is the workhorse of Elixir applications—caches, counters, connection pools, and background workers are all GenServers.

defmodule Counter do
  use GenServer

  def start_link(initial), do: GenServer.start_link(__MODULE__, initial, name: __MODULE__)
  def increment, do: GenServer.cast(__MODULE__, :inc)
  def value, do: GenServer.call(__MODULE__, :value)

  @impl true
  def init(initial), do: {:ok, initial}

  @impl true
  def handle_cast(:inc, count), do: {:noreply, count + 1}

  @impl true
  def handle_call(:value, _from, count), do: {:reply, count, count}
end

Supervisors and “Let It Crash”

A supervisor is a process whose only job is to start, monitor, and restart other processes. Instead of writing defensive code for every possible failure, you let a process crash and trust its supervisor to restart it in a clean, known-good state. Failures become isolated and recoverable rather than cascading.

children = [
  {Counter, 0},
  {MyApp.Cache, []}
]

# If a child crashes, restart just that child
Supervisor.start_link(children, strategy: :one_for_one)

Supervisors nest into supervision trees: supervisors supervising supervisors, all the way down to workers. This tree is the backbone of a fault-tolerant Elixir system. Details are in the official Elixir supervisor documentation.

Why This Matters for Real Products

The BEAM and OTP are exactly why Phoenix LiveView can hold hundreds of thousands of live connections, why a dropped WebSocket is a single isolated failure rather than a page-wide outage, and why Elixir is such a strong fit for real-time SaaS. We make that case in full in why Elixir Phoenix is the best framework for SaaS, and compare the runtime to alternatives in Elixir vs Go.

Frequently Asked Questions

What is the BEAM in Elixir?

The BEAM is the Erlang virtual machine that Elixir compiles to and runs on. It provides lightweight isolated processes, per-core preemptive scheduling, message passing, and fault isolation—the runtime features behind Elixir’s concurrency and reliability.

What is the difference between the BEAM and OTP?

The BEAM is the virtual machine—the engine that runs your code and schedules processes. OTP is the library of proven patterns (GenServer, supervisors, applications) built on top of the BEAM for structuring reliable, fault-tolerant systems. The BEAM is the runtime; OTP is how you build with it.

What is a GenServer?

A GenServer is an OTP behaviour for a stateful server process. It holds state and handles synchronous calls and asynchronous casts through standard callbacks (init, handle_call, handle_cast). It is the most common building block in Elixir applications.

What does “let it crash” mean?

“Let it crash” is the Elixir philosophy of not writing defensive code for every error. Instead, you let a process fail and rely on its supervisor to restart it in a clean state. Because processes are isolated, one crash does not corrupt or take down the rest of the system.

Build on the BEAM With Equantra

We build production Elixir Phoenix systems that lean on exactly these properties—concurrency, fault tolerance, and real-time delivery.

Hire Elixir developers, explore our Phoenix framework development practice, or get a free consultation.

Ready to Build Your SaaS?

Our team specializes in Elixir Phoenix, Ruby on Rails, Django, and Next.js. Let us help you ship faster with a dedicated engineering team at a fraction of the cost.