Note; a similar post from @adam that explores this question from a different angle is Status.app - check it out also!
Like many things in life, including glasses of water and black-and-white curvy symbols, the chat can be approached from different angles that that on the surface describe the same system, but underneath represent completely different world views, and consequently, different trade-offs, strengths and weaknesses.
Today at status, we treat the chat primarily as a messaging system. In this mental model, messages are pushed from the sender to the receiver, assuming that the receiver will be online and able to receive the message as it’s being sent. This system comes with several interesting properties that work well for live communications:
- Conceptually matches the act of sending a message to someone
- Low latency
- Low overhead for sender
- Well suited for synchronous, live communication
In the raw form of this model, messages are lost if the receiver is offline - the sender does not store them and there’s no one else around to do so either. Similarly, if a message is lost for networking reasons, it is lost forever, with no baked-in way of retrieving it. One could say that reliability and offline-capability are add-ons to the system. It is also the onus of the sender to prove that the message is useful - through proof of work or other means.
An alternate model for chat (or communications in general) is that of a distributed or replicated database. Here, every node is the holder of a database that can be replicated somehow between participants of the network - replication is the primary means of receiving a message - you append and synchronize, not send and receive.
This model comes with a different set of advantages:
- Reliability is an direct effect of the design
- Service degrades gracefully and naturally with limited connectivity and works well with alternate transports such as mesh networks, usb sticks or anything else that can get bits across.
- In a way, the receiver decides on the usefulness of syncning a particular log, and the sender is free to do as they want.
In a system like this, you can further play with the topology and layout by splitting up the storage responsibilities. Traditionally, a chat history is viewed and saved as a series of messages for one or more participants - the store contains all messeges from all participants.
In a log-centric view, each participant (at an abstract level) can store their own messages only - synchronization means fetching the message of the other participant without affecting your own log and sending a message means appending a message to your own log only, and letting the recipient synchronize the new message when available - the full chat history can then be stitched together “on the fly”. Group chat? Add multiple logs together and use a graph to determine a faithful ordering.
What about storage? Well, you primarily store your own messages in a log on your own device. You can then choose to replicate them to any storage, and the mechanism for retrieving them is the same, regardless where they are stored - swarm, IPFS, USB stick. Likewise, you can choose other logs to replicate that interest you - such as the log created where your contact writes their side of the dialogue to you.
Equally interesting is the fact that there are no “special” participants required for this system to work. True to decentralization, every node is equipped to be self-sufficient in its capabilities. It works when connectivity is down, when there’s no server around.
To get a feeling for the technical implemenation of a distributed log, and how it works, check out The Log: What every software engineer should know about real-time data's unifying abstraction | LinkedIn Engineering, but as developers, we should already have a good feeling for it, because we use one almost every day - git.
To delve into the philosophical aspects and add security on top, and how to build a chat or a twitter specifically on top of this, a gold mine is the stories section of scuttlebutt.
The question to ask ourselves now is - which of these mental models best agrees with the product we’re building - a secure decentralized messenger for a device that often is offline and may potentially be used in a mesh setting?
The compendium holds links to more material on this topic as well, including several interesting messengers like Briar, Tox and SSB that in some shape of form make use of these principles.