Tell, Ask, or a remote send) enqueue concurrently, and the actor’s dispatcher is the single
consumer that dequeues in the mailbox’s order. This is what gives each actor its single-threaded processing guarantee.
Control-plane messages such as PoisonPill travel on a separate system mailbox and always take priority, so a custom
mailbox only ever handles user messages.
Setting a mailbox
PassWithMailbox as a SpawnOption:
Setting a mailbox
WithMailbox, the actor uses UnboundedMailbox, a lock-free FIFO queue.
Built-in mailboxes
- UnboundedMailbox (default): Capacity: Unbounded. Ordering: FIFO. On overflow: Grows.
- UnboundedSegmentedMailbox: Capacity: Unbounded. Ordering: FIFO. On overflow: Grows.
- UnboundedFairMailbox: Capacity: Unbounded. Ordering: FIFO per sender, round-robin across senders. On overflow: Grows.
- BoundedMailbox: Capacity: Bounded. Ordering: FIFO. On overflow: Blocks the producer.
- NonBlockingBoundedMailbox: Capacity: Bounded. Ordering: FIFO. On overflow: Drops to the dead-letter stream.
- UnboundedPriorityMailBox: Capacity: Unbounded. Ordering: Priority. On overflow: Grows.
- UnboundedStablePriorityMailbox: Capacity: Unbounded. Ordering: Priority, FIFO on ties. On overflow: Grows.
- BoundedPriorityMailbox: Capacity: Bounded. Ordering: Priority. On overflow: Drops to the dead-letter stream.
- BoundedStablePriorityMailbox: Capacity: Bounded. Ordering: Priority, FIFO on ties. On overflow: Drops to the dead-letter stream.
Unbounded FIFO
UnboundedMailboxis the default: a lock-free multi-producer, single-consumer queue with no capacity limit. It never blocks and never drops. Use it unless you have a reason not to.UnboundedSegmentedMailboxstores messages in pooled, fixed-size array segments. It keeps the unbounded, never-drop behavior but improves cache locality and holds steady-state allocations near zero, which helps actors under sustained high throughput.UnboundedFairMailboxgives each sender its own sub-queue and drains them round-robin, so a chatty sender cannot starve quieter ones. Messages from the same sender stay FIFO. Use it for multi-tenant actors or protocol handlers serving many clients.
Bounded FIFO
BoundedMailboxhas a fixed capacity and applies blocking backpressure to local senders: when full,Enqueueblocks the producer until space frees. A message that arrives over remoting is never blocked: when the mailbox is full it is refused withErrMailboxFulland routed to the dead-letter stream, because its producer is the connection’s inbound dispatcher and blocking it would stall every receiver sharing the connection.NonBlockingBoundedMailboxhas a fixed capacity and never blocks. Its capacity is rounded up to the next power of two. When full,EnqueuereturnsErrMailboxFulland the runtime routes the excess message to the dead-letter stream.
Bounded FIFO
Priority
Priority mailboxes take aPriorityFunc and dequeue the highest-priority message first:
Priority
true when msg1 should be processed before msg2. The stable variants additionally keep messages of equal
priority in arrival order; the plain variants leave that order unspecified.
Priority
UnboundedPriorityMailBoxandUnboundedStablePriorityMailboxare unbounded; the stable one preserves arrival order among equal priorities.BoundedPriorityMailboxandBoundedStablePriorityMailboxadd a fixed capacity. When full,EnqueuereturnsErrMailboxFulland the excess message is dead-lettered instead of blocking the producer.
Enqueue never
contends with the consumer.
When a bounded mailbox drops a message, the message is delivered to the dead-letter stream, where it can be observed.
See Event Streams for how to subscribe to
Deadletter events.Choosing a mailbox
- Default to
UnboundedMailbox; move toUnboundedSegmentedMailboxfor throughput-heavy actors. - Need a memory ceiling? Use
NonBlockingBoundedMailbox(drop to dead letters) orBoundedMailbox(block the producer). - Need fairness across senders? Use
UnboundedFairMailbox. - Need priority ordering? Use a priority mailbox; pick a stable variant when equal-priority messages must keep arrival order, and a bounded variant when you also need a capacity ceiling.
Writing a custom mailbox
Implement theMailbox interface and pass it with WithMailbox:
Writing a custom mailbox
Enqueue
routes the message to the dead-letter stream. Use the built-in mailboxes in actor/ as a reference.