Message Passing Versus Shared Memory
Message passing structures concurrency as communication — actors, channels, queues own their state — instead of threads synchronizing over shared memory, local or distributed.
Definition
Message passing is a concurrency model where processes or actors exchange immutable messages through channels or mailboxes, and no state is shared. Concurrency correctness shifts from lock discipline to protocol design. The same model scales from in-process channels to distributed queues, at the cost of copying and latency versus direct shared access.
Context and scope
Erlang and Akka actor systems, Go channels, Rust channel APIs, and distributed messaging. CSP and actor model are the two formal traditions.
Common misconceptions
- Message passing removes concurrency bugs — it relocates them: deadlocks become protocol waits and mailbox overflow instead of lock cycles
- Messages are zero-cost — messages copy (or move); large hot state passed per message can cost more than guarded shared access
- The model is only for distributed systems — in-process channels are a competitive local design, avoiding locks while keeping single ownership
Anti-patterns
- Sharing mutable state by sending references through channels and keeping the races the model was meant to remove
- Blocking channel operations without timeout or select, recreating distributed deadlocks locally
- Funneling every operation through one actor mailbox and serializing a supposedly parallel system
Related concepts
Related examples
Authoritative source
What it is
Shared memory asks: who may touch this data and when. Message passing asks instead: who owns this data — exactly one actor — and how do others request action on it. Ownership replaces locking as the correctness mechanism.
How it works
Actors or goroutines own private state and communicate via channels: send, receive, and select over multiple channels. Message immutability or ownership transfer prevents shared access. At scale the same shapes become distributed: queues, publish-subscribe, and request-reply over the network with serialization and delivery semantics added.
When to choose
State machines with clear ownership, pipelines of transformation stages, and any design that would otherwise need many locks. Keep messages small and ownership crisp; fall back to shared memory for genuinely hot read-mostly data with synchronized access.
Pitfalls
Mutable payloads smuggle sharing back in — enforce transfer discipline or deep copies. Channel deadlocks reproduce lock deadlocks with worse stack traces; always model timeouts. Hot single-mailbox actors bottleneck entire systems; partition actors by key when throughput demands it.