Process Archetypes: The Roles in the Gnome Village
The BEAM makes it easy to create thousands of processes. This is powerful, but only if you give each process a clear role. A process without a role becomes a small, confused god-object with a mailbox. Eventually it grows a personality disorder.
To avoid this fate, I use a simple model of five archetypes. Every process in a BEAM system fits one of them. If it doesn’t, it is probably doing too much.
The archetypes are not design patterns. They are behavioural roles. Think of them as job descriptions for the gnomes in the village.
The roles are simple: Workers do work. Resource owners keep state. Routers decide. Gatekeepers protect. Observers watch. That is the entire system. You can stop reading now.
Workers
A Worker handles exactly one task. It does the job, reports back, and disappears. The disappearing part is important. It keeps the world tidy.
Workers are the default choice when you need parallelism or simple isolation. Spawn one, give it a message, and let it finish. If it crashes, only one piece of work is lost. That is usually acceptable. If it isn’t, the Worker should not be doing that job.
Some Workers live in pools. These Workers might keep some configuration between jobs. They still perform one job at a time, but they do not vanish afterwards. They sit quietly until needed again. This is the polite version of a thread-pool, without the traditional thread-pool problems.
Workers embody the BEAM’s idea of cheap concurrency. You hire many, pay them little, and expect them to fail occasionally.
Resource Owners
A Resource Owner does one thing: it owns state. A cart, a user session, a WebSocket, a payment intent. Anything that needs a clear owner becomes a process.
A Resource Owner serializes access by receiving one message at a time. There are no locks, no strategies, and no passive-aggressive comments in code reviews about “thread safety”. A Resource Owner is always thread-safe, because it is the thread.
Aggregators are a subtype. They collect rolling data or maintain sliding windows. Same principle, but more numbers.
If the system relies on invariants, the Resource Owner is where those invariants live. You do not put them in five layers of frameworks. You put them in a process that owns the data. It is the simplest possible model, which is why it works.
Routers
A Router never owns anything. It reads a message and forwards it to the correct place. That is all.
Sometimes the Router fans messages out (broadcaster). Sometimes it sends them to a single target (director). In both cases it has no state and no emotional attachments. A Router that remembers things, other than where to send messages, has abandoned its post.
Routers keep the architecture clean. If a Router becomes complicated, the system design is wrong. If a Router starts holding state, the system design is very wrong. This is usually how accidental bottlenecks begin.
Gatekeepers
A Gatekeeper protects something. It limits, delays, sequences, or blocks. It exists because the outside world cannot be trusted.
There are three common types:
Flow controllers enforce ordering or stage boundaries. Rate limiters slow the producers down so you don’t melt your downstream systems. Circuit breakers give up early when something is clearly on fire.
The Gatekeeper role is simple: let good messages through, keep bad messages out, and contain the blast radius. Without Gatekeepers, a small outage becomes a distributed festival of sadness.
Observers
Observers do not own state and do not do work. They watch other processes and respond to conditions.
Sentinels watch for overload, timeouts, and stalled flows. Supervisors watch for death, restart children, and otherwise mind their own business.
Supervisors are the managers of the village. They never bake bread or carry logs. They only decide who should be restarted and when. A Supervisor that does real work is a future incident waiting to happen.
Observers tie the system together without touching the logic.
Why Roles Matter
Most problems in process-oriented systems come from role confusion. A Resource Owner that tries to route requests becomes a bottleneck. A Router that stores state becomes a single point of failure. A Worker that lives too long becomes a Resource Owner by accident. A Supervisor that does real work becomes your next 3 AM story.
Clear roles reduce cognitive load. They make supervision trees predictable. They make debugging obvious. When each process has one job, everything is easier to trace, reason about, and restart.
Good systems are built from small pieces with strong opinions about what they do.
Looking Ahead
This post introduced the five archetypes. Next, I will walk through each role in detail, with examples and the small mistakes that make big problems.
To make this practical, I’ll also publish a set of minimal examples in Erlang, Elixir, and a few other languages. The BEAM versions will be small. The non-BEAM versions will demonstrate why the BEAM versions are small.
One archetype per post. One job per process. Life is easier that way.
