Table of Contents
Mailbox
A mailbox is a bounded, addressed queue: one process (or task) delivers messages into it, and another consumes them out, typically in FIFO order. Unlike a CSP channel, a mailbox is usually owned by a specific process rather than being an anonymous rendezvous point between two ends. Unlike Linda's tuple space, a mailbox is addressed to one recipient, not searched by content across a shared pool.
mbox_t inbox; mbox_create(&inbox, 16); // bounded to 16 messages void producer(void) { mbox_send(&inbox, &msg); // blocks if the mailbox is full } void consumer(void) { struct message msg; mbox_recv(&inbox, &msg); // blocks if the mailbox is empty }
Bounded capacity as backpressure
Because a mailbox has a fixed capacity, a producer that outpaces its consumer eventually blocks on send rather than growing memory usage without limit. This gives the system natural backpressure: a slow consumer visibly stalls its producer instead of silently accumulating an unbounded backlog. The tradeoff is a design choice every mailbox-based system has to make explicitly: pick a capacity too small and producers stall under normal bursts; pick it too large and a backed-up consumer can hide a real problem for a long time before anyone notices.
Where this shows up
Mailboxes are the standard inter-task communication primitive in RTOSes like FreeRTOS (xQueueSend/xQueueReceive, which are really a generalized mailbox) and Zephyr (k_mbox_put/k_mbox_get), since embedded systems need a way to hand data between an ISR and a task, or between two tasks, without dynamic allocation on the hot path. Erlang and Elixir also model inter-process communication as mailboxes at the language level, where every process has an implicit inbox that send/receive operate on.
