Phoenix Channels - groups or no groups?


I tried searching to see if a question along these lines had been posted already but couldn’t find anything. I am working on a Phoenix app that will communicate with a bunch of clients. Let’s pretend I am creating something similar to WhatsApp.

To avoid the overhead of HTTP requests, I have each client join their own channel “user:${user_id}” and most of the general app communication takes place through there.

But WhatsApp also has groups - the way I implemented this at first was to create a new channel for each group “group:${group_id}” and have each client join the channel for every group they are in when they connect to the socket. Messaging within the group is then very easy - implement a handle_in function that broadcasts the message. To handle offline users, I use Presence to track them and then queue a message in the database for them to download next time they connect to their user channel.

I have started to think though, is this really the best way? It feels like as the application grows, each user will end up in more and more groups and would be joining a new channel for every single one. The number of channels will get out of hand. Given that the server knows the members of each group in advance, and every user already has their own channel, would it maybe be better to scrap the group channels and just have each client send messages to the server specifying the target group, then have the server call Endpoint.broadcast to send the message out to each member of the group via their own user channel one-by-one?

I guess in theory both approaches work, but is there one that is likely to scale better? I am not sure what the marginal cost of adding channels is, versus the marginal cost of the server sending a message to 10 different channels rather than to one channel containing 10 people.

This feels like a relatively common situation to run into, so I would appreciate any help anyone can give.


I believe the Discord crew ran into this problem at scale - though I don’t think they are using channels specifically…

Either way, perhaps worth a read: