Actor Model
The actor model structures computation as autonomous actors — private state, asynchronous mailbox, one message at a time — eliminating shared-memory synchronization by construction.
Definition
An actor is a unit of concurrency with three primitives: send asynchronous messages to other actor addresses, create child actors, and change private behavior for the next message. Only one message processes at a time per actor, so internal state needs no locks. Location transparency lets the same model span one process or a cluster; supervision trees add failure isolation.
Context and scope
Implemented in Erlang and Elixir, Akka, and Orleans (virtual actors). Applied wherever massive stateful concurrency with isolation beats shared-state threading.
Common misconceptions
- Actors are lightweight threads — actors are identity plus mailbox; execution rides a runtime scheduler, and millions of actors can idle at memory cost
- The actor model removes race conditions — it removes data races by construction; logical races — message ordering between actors — remain design work
- Actors make distribution trivial — the model is location-transparent; the engineering of partitioning, delivery guarantees, and supervision at cluster scale is the hard part
Anti-patterns
- Making one actor a singleton bottleneck through which every request serializes
- Blocking inside an actor on synchronous calls and deadlocking its mailbox — and the callee mailbox back
- Designing chatty actor conversations where one business operation becomes dozens of messages
Related concepts
Related examples
Authoritative source
What it is
Shared state asks threads to coordinate through locks. The actor model answers with ownership: state belongs to an actor, reachability happens through messages, and processing is serialized per mailbox. Coordination disappears because contention disappears.
How it works
Each actor consumes mailbox messages one at a time, mutating private state without locks. Message delivery is asynchronous; ordering guarantees vary by runtime — Erlang guarantees per-sender-pair ordering, others do not. Supervision hierarchies let parents restart failed children with policies, turning failure into a structural concern. Virtual-actor runtimes (Orleans) activate actors on demand by identity, hiding placement entirely.
When to use it
Many independent stateful entities — sessions, devices, game entities, workflow instances — where per-entity serialization is exactly the desired semantics, and fault isolation per entity matters. Shared-state thread pools with fine-grained locking serve better when state is global rather than per-entity.
Pitfalls
Mailbox overflow under burst is the actor stress mode — apply bounded mailboxes with backpressure signaling. Ask-patterns (request-response) reintroduce blocking and deadlock risk; prefer tell semantics with explicit correlation. Hot actors must be partitioned by key, and splitting stateful actors requires migration design. Testing needs mailbox-aware harnesses; deterministic simulation frameworks exist precisely because plain tests cannot see interleavings.