Skip to main content

Actor Model

The actor model has isolated actors hold private state and communicate only by async messages, eliminating locks and data races. It enables massive concurrency and supervised fault tolerance.

Type
Concurrency
When to Use
High Concurrency, Stateful Entities, Fault Tolerance

The actor model is a concurrency paradigm in which the unit of computation is an actor: a lightweight entity that owns private state and communicates with other actors solely by sending asynchronous, immutable messages. Because no state is shared, there are no data races and no need for locks. Actors process messages one at a time from their mailbox, so each actor's internal logic is effectively single-threaded.

How It Works

Each actor has a mailbox (an inbox queue) and a behavior that defines how it reacts to messages. On receiving a message, an actor can: update its private state, send messages to other actors, and create new actors. Messages are delivered asynchronously and processed sequentially per actor, which serializes access to that actor's state without locks. Runtimes (Erlang/OTP, Akka and Pekko on the JVM, Microsoft Orleans, Elixir) schedule millions of actors over a small thread pool. Fault tolerance comes from supervision hierarchies: a parent actor monitors children and restarts them on failure, embodying the "let it crash" philosophy.

When to Use It

Use the actor model for systems with vast numbers of independent, stateful entities and high concurrency: telecom switches, multiplayer game servers, IoT device twins, chat and presence systems, and distributed stateful services. It excels when isolation, location transparency (actors can live on different nodes), and resilient supervision are valuable.

Trade-offs

Asynchronous message passing makes control flow harder to follow and debug than direct calls; there is no stack trace across actors. Message ordering guarantees are limited (usually per-sender), and at-least-once delivery requires idempotent handling. Designing supervision trees and avoiding mailbox overflow (unbounded backlog) takes skill. The model can be overkill for simple, shared-nothing parallelism better served by a thread pool, and debugging distributed actor systems is genuinely demanding.

Related Patterns

Each actor's mailbox is a producer-consumer queue, the model is a fine-grained form of event-driven-architecture, and it shares dispatch concerns with the reactor pattern.

Example

A multiplayer game models each player session as an actor holding that player's state. Game events arrive as messages; each session processes them sequentially, so its state never races. A supervisor restarts crashed sessions from the last snapshot, and actors migrate across nodes as the cluster scales to millions of concurrent players.