by toast0 | 2026-03-03 05:21:26+00:00
> Do BEAM applications not use an actual databse? How is crash tolerance guaranteed? In a typical application I'd write crash tolerance would be handled by the DB. So would transactionality.

OTP includes mnesia, which is a distributed, optionally transactional database (for mostly key-values); it's not the easiest thing to use, but it's there. You can also connect out to an external database, there's no requirement to stay within BEAM.

If you want database changes to be persisted to disk, you have to persist them. If you want to wait to show success until the changes have persisted, you have to wait. I don't see how the runtime you use changes that, so I'm not really sure I understand your question? You don't generally persist the process mailboxes; if a process or node crashes, its mailbox is lost.

In a distributed system you rapidly run into two generals questions, which are always challenging to address. If I send you a message, and I receive a reply, I know you received it. But if I send you a message and don't receive a reply, I don't know what happened; maybe you never got it, maybe you received it and crashed, maybe you replied but I never got it, maybe you replied but I crashed or timed out and moved on. Again, that's the case regardless of runtime. It's hard to find systems with 100% uptime on all individual parts, so you have to set a reasonable timeout on communication, and you have to deal with picking up the pieces when that happens.

> I assume these problems are solved, but the article doesn't demonstrate the solutions.

There isn't really a general solution to the systems are hard problem. You have to pick what's appropriate for your system, and many systems will need different solutions for different parts. As an example from my time at WhatsApp: the table indicating which process held the tcp chat connection for a user was never persisted to disk; otoh (towards the end of my time) text messages would not be acknowledged to the client until they were either acknowledged by the destination client or in memory or on disk on multiple servers; the receiving client was responsible to deduplicate messages in cases where the sender did not receive an ack and resent or when one of the redundant servers was offline when the message was delivered and it delivered it again later. Many things less critical than messages were acknowledged when accepted, without waiting for confirmed persistance. Many user actions would not be automatically retried on a timeout or other failure --- letting the user decide what to do.

I guess maybe the question is why use BEAM if it also doesn't solve the general systems are problem? IMHO, the reason to use BEAM is because it helps you structure your system around easy to reason about parts. You've got to do some work to get messages into the right mailboxes, but the process working on a mailbox usually reads a message, does the work for the message, sends a reply and then gets to the next message in its mailbox. Each individual process can be simple and self-contained. Explicit locking can (hopefully) be avoided by ensuring only a single process is responsible for some piece of state, and that accessing that state is done by sending the responsible process a message. BEAM takes care of locking around the mailbox, but you don't need to worry about it.