Instant Messengers VS Bad Internet

For the past 5 days now, my internet has barely existed. The sudden extreme winter weather has knocked it out for longer than it's been up. It started as the internet toggling off and back on, but now we only get the occasional blip of internet activity before it disappears.

This has made trying to keep in contact with others quite a challenge. These conditions are a perfect stress test to see which instant messengers perform best under spotty internet connections. Perhaps my experiences will help someone else decide on what messenger to use.

Most of the communication was done through the mobile apps on Android. They have desktop equivalents which do behave slightly differently, but not significantly enough that it would change their ranking. I only used messengers I already had, because there was no way to download new ones. So, sorry if I don't cover your favorite.

1. Signal Messenger

At the top, the best performing messenger is Signal, by and far. This is kind of surprising, considering Signal's encryption relies on rotating the keys based on previous messages. I'd expect missing or delayed messages would cause keys to fall out of sync, but this hasn't been the case. I've never had an issue with Signal's keys, showing just how robust its protocol is.

Signal's design means every message you receive is stored locally. With no internet at all, you can continue to read these messages, because no connection is required to read local files. This was great because if I read a message, I could always read it again.

The downside of a local-only database is that the size will grow bigger than the device can handle, given enough time. Signal lets you set a maximum size for your history before it starts deleting your earliest messages. For privacy and security, this is great, but some people don't want that. I set it to a size where I can read a decent amount back in time (I can go back through one year of messages), and for the current situation, it's working fine. If someone recently sent me something I need to reference, I know I can always bring it up. If it's important, I'll record it somewhere else for long term storage.

Sending and receiving messages is handled seamlessly. Signal has an indicator on every message that shows you if the message is sending, has been received by the server, has been received by the conversation partner, and if it has been read by the conversation partner. You can use these indicators to check very clearly what messages have been dropped or not. But over these past few days, I haven't had any messages drop. I've rarely had some drop in the past while the connection was strong, but that was likely somewhere further down the chain of travel.

When sending a message, it will continue trying to send until it has finished. This meant I didn't need to keep monitoring it to send, like I did with FluffyChat. This allowed Signal to send messages during shorter connections than the other messengers could.

If the message has yet to send, you can select the message and delete it. This stops it from trying to send. Very helpful if a message is now outdated.

Similarly, it will continue to check for messages and status updates in the background. No need to manually fiddle with it. If you get a small blip of internet, it will immediately fetch what it can. No babysitting necessary.

So basically, when there's no internet, the conversation goes on pause. When the internet comes back, it automatically syncs up what's been queued. That queue alone makes Signal the most practical for handling spotty internet.

2. FlufflyChat

FluffyChat is a client for the Matrix protocol. I use the encryption option for all my chats through Matrix. In the past using Element, the client made by the same team building Matrix, this has lead to issues where keys would get out of sync. The only way to fix it would be for the person your talking to to say they're not able to decrypt your messages, then restart your client to re-sync.

I expected that the client made by the official team would be built to best use the protocol. FluffyChat surprised me. The branding makes it seem gimmicky, but it's actually a lot more robust.

In FluffyChat, if you try to send a message when you have no internet, it will eventually time out. The message then stays at the bottom of the chat. You have the option to attempt resending it. In Element, this usually desyncs the keys and when it goes through, the person receiving won't be able to decrypt it. But in FluffyChat, I've only had this happen once.

There is a slight issue where resending messages might cause them to display out of order for you. But I've found they always send in the order you resend them. If you restart the app, they will show up in the right order again.

FluffyChat will also continuously poll in the background for incoming messages like Signal does. This makes receiving messages easier than sending them. The timeout on sending messages means you have to notice when the internet is back online, quickly open the app, and resend the message. At least they're not lost, but I would like an option to be able to infinitely retry. I'll consider opening a feature request once I get internet back.

To get around this, I've been running a script that continuously pings for a connection, and if it succeeds, plays a notification jingle. This alerts me to quickly resend the message while there's still internet. I really shouldn't need to create my own external tools for this.

FluffyChat splits the difference between local and online storage by caching your most recent messages. If you don't have internet, you can always open the app and see what was recently sent to you. To scroll back further, you'll need internet to load those messages.

3. SchildiChat

SchildiChat is a fork of Element Android. I've found it tends to be more stable. Unfortunately, it has inherited Element's poor network compatibility.

If you try to send a message while the client is offline, it will keep the message and continuously try to send it, same as Signal does. (This behavior differs from the desktop version of Element. Don't ask me why.) However, more often than not, once the message finally sends, it will not be possible for the person who receives it to decrypt the message. This requires restarting and resending the message anyways, so this isn't practical.

It caches recent messages and polls for new messages in the background, same as FluffyChat.

The frequent de-syncing of keys is the only thing holding it back. If this gets fixed, it will be as good as Signal.

4. Discord

Discord was the absolute worst, by a long shot.

Every time Discord starts up, it must first establish a connection with the server and re-sync everything. The long startup time means you're likely to miss the window of opportunity for when the internet is active.

Once the app does load, it needs to download the messages for the chat you're looking at. It doesn't matter if you already downloaded them the last time you had Discord open. It barely caches anything. You might get lucky and get to see a couple messages from the chat you last had open, but that's it.

If you try to switch to other chats, you'll be greeted with a wall of blank skeleton loaders. Placeholder assets that pretend to be content while the content loads. Again, nothing cached.

If you have Discord open at the same time that the internet reconnects, Discord is slow to pick up on this, and you might miss your window to do anything. It will say it's still trying to connect, while all the other apps have already connected. You're better off just quitting and restarting the app.

Once you've gotten lucky enough to establish a connection, you can send a message. Hooray!

But it can't be that simple. Every time you send your message, it enters a quantum state of being both sent and unsent. If you still have connection, then your message will probably make it through. If you lose connection part way through, then it could go a few different ways.

Your message might get caught in The Infinite Grey Purgatory. The message stays at the bottom of the chat, grayed out, unsent. You can't interact with this message at all, and it will never send. If you restart the app to get the connection back, these messages will be lost forever.

If that doesn't happen, your message might get swallowed up by The Void. You send the message, and it's just.... gone. Poof. No more message.

It would be easy to assume that this means the message didn't send. But no, we're dealing with quantum states here. On your end, there is no message. But on the other end, there's a chance that the message either did not send, or it did. You have no indication either which way. The only way to find out is to restart the app and reconnect so everything can re-sync, allowing us to observe and collapse the state. Groovy.

I want to point out that Discord is the only chat on this list that does not have encryption. It doesn't have any complicated algorithms to keep in sync. It's simply taking a packet of data from one place to another, then displaying it. This app should have the easiest time out of all of them working under these conditions.

Discord devs have clearly taken an ivory tower approach to its design. It's built to only work in the most optimal conditions. From their major city offices, they'll never have to deal with big data connection losses, so it never comes up in their design plans. It's not an issue for them, so they don't plan for it. They've too busy removing bot APIs and adding more Nitro buttons.

The app is written with the expectation that you'll always have an internet connection. After all, you need internet to be able to send and receive messages, right? But this is a mobile app. A phone is going to be traveling who knows where with uncertain conditions constantly. A good design will account for this.

We are NOT in an age where internet is always available. Especially not high speed internet.

Internet is not cheap, even more so on mobile plans. Many people are still paying by the GB. If your app's approach is to re-download everything on each launch, then you are abusing these people's data plans.


Mobile devs, if there's anything you take away from this, make it cache cache cache! If you can cache it, do it! It's up to you to decide what the right balance is, but do not treat internet like an infinite resource. Make your app usable with not internet at all.

I hope devs, especially mobile devs, will take sub-optimal conditions into consideration more often in the future. Too often now I see aspirations of designers building for computers with hardware requirements that have yet to be released, or building around structures that don't exist like "always online". This needs to stop. Design for the real world.

I want to give praise to the Signal and FluffyChat devs for providing such a solid communication experience. If you need to ensure an ability to communicate through unstable internet connections, I would recommend one of those two.