Honest reflections on the runtime that was twenty years ahead of its time
Joe Armstrong created something extraordinary. Not just a programming language -- a runtime, a philosophy, a complete system for building software that does not go down. He did this in the late 1980s at Ericsson, solving problems that the rest of the industry would not even recognize as problems until the internet scaled past what anyone expected. He passed away in 2019, and the computing world lost one of its most original thinkers. Understanding Erlang is partly about honoring that legacy, but mostly about understanding why the BEAM works the way it does.
The BEAM is not a virtual machine in the way the JVM is a virtual machine. Calling it a VM is technically accurate and deeply misleading. The JVM runs bytecode. The BEAM runs a distributed operating system for concurrent processes. It has its own scheduler, its own memory management per process, its own garbage collection per process, its own I/O subsystem. When you start a BEAM instance, you are not starting an application. You are starting a runtime that can manage millions of lightweight processes, each with its own heap, each independently garbage collected, each communicating only through message passing. That is not a VM feature. That is an operating system architecture.
Understanding Erlang is not about writing Erlang. You will write Elixir. But Elixir compiles to BEAM bytecode, runs on the BEAM scheduler, uses BEAM processes, and inherits BEAM guarantees. When something goes wrong -- and it will -- the error messages, the crash dumps, the observer tool, the debugging workflow all speak Erlang underneath. You do not need to be fluent in Erlang. You need to be literate. The difference matters.
The preemptive scheduler is the detail that separates the BEAM from everything else. Most runtimes use cooperative scheduling -- your code yields control voluntarily. The BEAM uses preemptive scheduling with reduction counting. Every process gets a fixed number of reductions (roughly, function calls) before the scheduler takes control back. This means no single process can starve the system. No infinite loop can freeze the runtime. No slow query can block other work. This guarantee is baked into the runtime, not the application. You cannot break it even if you try.
This is why the BEAM matters: it provides guarantees at the runtime level that other platforms require application-level code to achieve, poorly, partially, and with constant maintenance.
Conclusion #
You do not learn Erlang and the BEAM to write Erlang. You learn them to understand the machine your Elixir code runs on. Every performance characteristic, every concurrency guarantee, every fault tolerance property of your Elixir application ultimately comes from the BEAM. Knowing how it works transforms you from someone who uses Elixir to someone who understands why Elixir behaves the way it does. If you have an integrator's mindset -- connecting systems and understanding how things fit together -- this is essential knowledge.
Predictions #
-
Reading Joe Armstrong's thesis will be one of the most intellectually stimulating experiences in this entire curriculum
-
The preemptive scheduler will make you realize how fragile cooperative scheduling (like Ruby's GVL) actually is
-
You will start using Observer in development and wonder how you ever debugged concurrent systems without it
-
Understanding BEAM processes will make Docker containers feel heavyweight by comparison
-
You will develop a deep respect for Erlang's design even if you never write production Erlang code