The Supervision Tree
Actors are organized in a strict tree structure. Every actor (except the root) has exactly one parent, called its supervisor. When a child actor crashes, it does not handle the error itself — it reports the failure up to its parent, which decides how to respond.
This creates a clean separation of concerns: worker actors do work, supervisor actors handle failures. A worker actor's code contains zero error-handling logic for unexpected failures. It just does its job and crashes if something goes wrong.
Root Guardian
│
┌──────────┴──────────┐
UserSupervisor OrderSupervisor
│ │
┌─────────┴──────┐ ┌───────┴───────┐
WalletActor ProfileActor CartActor PaymentActor
Supervision Strategies
When a child crashes, the supervisor applies one of four strategies:
| Strategy | What Happens | When to Use |
|---|---|---|
| Resume | Keep the actor running with its current state | The error was harmless; state is still valid |
| Restart | Kill the actor, discard its state, start a fresh instance | State is corrupted; a clean slate is needed |
| Stop | Terminate the actor permanently | The failure is unrecoverable; the actor is no longer needed |
| Escalate | The supervisor crashes itself, passing the problem to its parent | The supervisor does not know how to handle this failure type |
The Escalate strategy is what makes the tree powerful. Failures bubble up until they reach a supervisor that knows how to handle them. If nothing can handle it, the root crashes — which is a controlled, visible failure rather than a silent corruption.
One-for-One vs. All-for-One
Supervisors also decide the scope of their response:
One-for-One: Only the crashed actor is affected. Its siblings continue running normally. Use this when workers are independent of each other.
Workers: [A] [B✗] [C]
After: [A] [B'] [C] ← only B is restarted
All-for-One: If any one worker crashes, all workers are restarted together. Use this when workers are tightly coupled — if one is in a bad state, the others are likely inconsistent too.
Workers: [A] [B✗] [C]
After: [A'] [B'] [C'] ← all three are restarted
A concrete example: imagine a supervisor managing a TCPConnectionActor and a PacketProcessorActor. The Packet Processor depends on the TCP Connection to function. If the TCP Connection crashes, the Packet Processor is now in a meaningless state — it has no connection to process packets from. An All-for-One strategy restarts both, ensuring they come back in sync.