BEAM Erlang Campus

Erlang lesson

Erlang processes and message passing explained

Erlang processes are lightweight, isolated actors. They do not share memory the way many beginners expect. Instead, they send messages. That single design choice changes how you reason about concurrency.

Why Erlang processes feel different

An Erlang process is not just a smaller operating-system thread. It is a separate unit of work with its own mailbox and state boundary. That means one process cannot silently mutate another process’s data. Communication becomes explicit because the only normal way in is through messages.

This is one of the biggest reasons Erlang systems are easier to reason about under concurrency. Ownership stays local. Coordination happens through protocols. Hidden shared-state bugs become much less common.

What message passing gives you

Message passing makes boundaries visible. If one process wants information from another, it has to ask. If it wants to update state, it has to send a request in a defined format. That creates clearer APIs and cleaner ownership.

For beginners, this is the right way to frame concurrency in Erlang: not “many things happening at once” but “isolated actors collaborating through messages.” Once that idea lands, OTP makes much more sense.

Pid = spawn(fun() -> loop(0) end).
Pid ! increment.
Pid ! {get, self()}.

How a process loop works

A stateful Erlang process is often just a recursive loop around receive. It waits for messages, reacts to one, updates its local state if needed, and calls itself again. The recursion keeps the process alive while preserving the idea that state is passed forward explicitly.

This is a crucial bridge between recursion and concurrency. Instead of thinking about a while loop over a mutable object, think about a process receiving one message at a time and moving to the next state version.

Common beginner mistakes with processes

A common mistake is treating a process like an object instance with direct field access. Another is forgetting to reply to the caller in request-response patterns. Learners also sometimes send vague messages that do not form a stable protocol.

The best fix is to design message shapes clearly. Use tuples such as {get, From} or {put, Key, Value}. State what each message means, what reply it expects, and whether the process should change state afterward.

How this connects to recursion and OTP

Processes and message passing sit between the simpler functional pages and the OTP pages. If you skip this middle step, OTP can feel like a framework without a reason. If you understand the loop-plus-mailbox model first, OTP becomes the structured version of something you already grasp.

That makes this one of the most important pages in the whole site architecture. It answers the beginner question “how does Erlang actually do concurrency?” in a form that naturally leads into GenServer and supervision.

A tiny message-passing walkthrough

If a process receives {get, From}, it can reply with From ! {value, State}. That tiny pattern teaches several core ideas at once: the process owns the state, callers must ask explicitly, and replies are just messages too. Nothing special is hidden behind the scenes.

Once that feels natural, a learner is much better prepared for OTP callback patterns like handle_call and handle_cast.

Why this page has real search potential

Searchers for erlang processes or erlang message passing are often looking for a clearer mental model than the official docs alone provide. They want the “why” behind mailboxes, isolation, and state ownership. That makes this topic especially valuable as a long-tail explanatory page.

Strong content here also reinforces other pages on the site, because recursion, OTP basics, and supervisor thinking all gain context when this concurrency page is solid.

What to practice next

  • Write a tiny loop that handles one increment message.
  • Add a {get, From} message that replies back.
  • Name the process owner of the state in one sentence.
  • Then continue to OTP basics.

Frequently asked questions

Do Erlang processes share state?

No. Normal Erlang processes do not share mutable state. They communicate by sending messages.

Why is message passing useful?

It keeps ownership explicit, makes protocols visible, and reduces many shared-memory concurrency problems.