Back to articles
Apr 17, 2026 - 2 MIN READ
Clever but risky Elixir patterns

Clever but risky Elixir patterns

Selective receive is a hidden Elixir behavior where a process looks through its waiting messages for one match, while the other messages stay there and can slowly make the process slower.

Roslan Saidi

Roslan Saidi

In Elixir, we create a process that can wait for a specific message:

receive do
  {:ok, data} -> data
end

Kinda looks simple. But the weird part is, if the mailbox already has many other messages that do not match {:ok, data}, Elixir will scan through them one by one until it finds the matching one. Those unmatched messages are not removed. So over time, the process mailbox can fill with useless messages and every receive becomes slower. That is what makes it risky: the code looks correct, but the process becomes slow quietly.

Why some of us miss it?

We often think “receive waits for the next correct message". But the real behaviour is “receive searches through all messages until it finds the correct one".

Simple use case

def wait_result do
  receive do
    {:result, value} -> value
  end
end

Now imagine the process receives many unrelated messages first:

send(pid, {:log, "start"})
send(pid, {:heartbeat})
send(pid, {:debug, 123})
send(pid, {:result, 42})

TLDR

Selective receive is risky because it fails silently. The code still works, but the mailbox slowly poisons the process.

© 2024 Roslan Saidi