Kernel Polling in the BEAM VM (Erlang/Elixir)
What is Kernel Polling?
Kernel polling is a technique where the operating system provides a way for applications to efficiently monitor many I/O resources (like sockets or files) at once. Instead of the application repeatedly checking each resource (polling), the OS notifies the application when any resource is ready for reading or writing.
- On Linux: uses `epoll`
- On macOS/BSD: uses `kqueue`
- On Solaris: uses `/dev/poll`
Why is it Needed?
Without kernel polling, the BEAM VM would have to check each socket/file descriptor individually (using `select` or `poll`), which becomes very slow as the number of connections grows (hundreds or thousands).
With kernel polling, the OS efficiently tracks all descriptors and only wakes up the VM when something happens, making it possible to handle tens of thousands of connections with low CPU usage.
Example Scenario
Suppose you have an Elixir server handling 10,000 WebSocket clients.
Without Kernel Polling
- The BEAM VM uses `select`/`poll` to check each socket.
- For every I/O event, it loops through all 10,000 sockets to see which are ready.
- This loop is slow and consumes a lot of CPU, even if only a few sockets have data.
With Kernel Polling (`+K true`)
- The BEAM VM registers all 10,000 sockets with the OS kernel polling mechanism (e.g., `epoll`).
- The OS tracks which sockets are ready for I/O.
- When a socket is ready, the OS notifies the BEAM VM directly.
- The BEAM VM only processes sockets that actually have data, skipping the rest.
- This is much faster and uses less CPU, even with huge numbers of connections.
Step-by-Step Flow (with Kernel Polling)
1. Server Starts: You start your Elixir app with `+K true` (kernel polling enabled).
2. Socket Registration: The BEAM VM opens sockets for each client and registers them with the OS kernel polling system.
3. Idle Waiting: The BEAM VM waits (sleeps) until the OS signals that a socket is ready.
4. Event Notification: A client sends a message. The OS detects data is available on that socket.
5. Wake Up: The OS wakes up the BEAM VM and tells it exactly which socket(s) have data.
6. Efficient Processing: The BEAM VM processes only those sockets, handles the data, and goes back to sleep.
7. Repeat: This cycle repeats, allowing the server to efficiently handle thousands of connections.
Code-Level Example
Suppose you run your server with:
iex - erl "+K true +A 1024 +P 10000000" -S mix run - no-haltCode language: Elixir (elixir)
- `+K true` enables kernel polling.
- Your Elixir app (using Cowboy, for example) opens thousands of sockets.
- The BEAM VM uses the OS kernel polling to efficiently manage all those sockets.
Visualization

Now, if everything is so good, the obvious question came into my mind, then after researching about it I found out the following
Why Isn’t Kernel Polling Always Enabled by Default?
- Not all OS support kernel polling, or support may be buggy on some platforms.
- On some systems, kernel polling can use more memory or have edge-case performance issues.
- For small numbers of sockets, the overhead of kernel polling may not be worth it.
- The Erlang/OTP team prefers conservative defaults for maximum compatibility.
Visual Flow
- The BEAM VM is a single OS process.
- All sockets are managed by the BEAM, but the OS kernel efficiently notifies the BEAM about I/O events.

Drawbacks of Kernel Polling
- Slightly higher memory usage (the OS needs to track all registered sockets).
- On some platforms, kernel polling APIs may have bugs or limitations.
- For very small numbers of sockets, the performance gain is negligible or negative.
- Complexity: Kernel polling code paths are more complex and may be harder to
Summary
- Kernel polling allows the BEAM to efficiently handle thousands of sockets in a single OS process.
- It avoids the O(n) scan of all sockets, making I/O scalable.
- It’s not always enabled by default due to compatibility and resource considerations.
- For high-concurrency servers, enabling it is almost always beneficial.
If you like this post http://coff.ee/y316nitka ☕️ consider supporting me with a coffee.

