How Elixir Handles Millions of Connections Without Breaking a Sweat
Ever wonder how Elixir manages massive concurrency? It’s not magic—it’s the Actor Model and the BEAM VM.
The Concurrency Question
We often hear that Elixir is the go-to language for high-concurrency systems like WhatsApp or Discord. But how does it actually handle thousands—or millions—of users simultaneously without crashing or slowing to a crawl?
What you see
From the outside, you just see a web application or a chat service. You send a message, and it arrives instantly. It feels like a single, massive program doing everything at once.
What actually happens
Under the hood, Elixir runs on the BEAM (the Erlang Virtual Machine). It doesn’t rely on OS-level threads, which are heavy and expensive. Instead, it uses Lightweight Processes.
- Processes: These are not OS processes. They are tiny, isolated units of execution managed by the VM itself. You can spawn hundreds of thousands of them on a single machine.
- The Actor Model: Each process has its own memory and state. They don’t share memory. Instead, they communicate by sending asynchronous messages to each other.
- Preemptive Scheduling: The BEAM scheduler constantly rotates through these processes. If one process takes too long, the scheduler pauses it and moves to the next, ensuring no single task can block the entire system.
Trace one example
Imagine a user sends a message in a chat app:
- A dedicated process is spawned for that specific user connection.
- The user process receives the message and sends it to a ‘Room’ process.
- The ‘Room’ process receives the message and broadcasts it to all other user processes currently in that room.
- Because each process is isolated, if the ‘Room’ process crashes, it doesn’t take down the user processes. The system can simply restart the ‘Room’ process and recover.
Why it feels magic
It feels instant because the system never waits for a lock. Since processes don’t share memory, there’s no ‘locking’ mechanism that causes threads to queue up and stall. The BEAM keeps the CPU busy by constantly switching between tasks, making the most of every core.
Takeaway
If you want to understand concurrency, don’t look at threads. Look at how your system isolates tasks. Start by reading about the Actor Model and how Elixir’s processes keep your app alive even when things go wrong.