Proposal on how to manage inactive users in a community

The Status community is growing day by day, and though we are still far from the 10K limit, or even the 5K switch to on request, we need to think how we are gonna address it before it’s too late.

Right now, there is no way to tell which user is active or not.
In a centralized community app like Discord, it’s not a big issue, because inactive users are just an entry in a table, but in Status, each user is a key in the community description that gets sent over the network. Also, we do have a 10K limit on the number of users because if everyone was active, the Waku network does have a limit.

So this brings me to my possible solution: We should add a button in the admin screen called “Kick inactive users”. This would call a function on the Control node that removes all users that haven’t sent a message since that date.
Clicking it would open a small form that would have two fields: “Last active” and “Date of joining”.
“Last active” is trackable using any message sent by that user in that community. This includes emoji reactions, so it’s pretty forgiving.
“Date of joining” is necessary as well, because if someone just joined today and didn’t send a message yet, they’d be kicked as well.
The combination of both these fields makes sure we only remove people that joined some time ago that haven’t posted in a while.

Using that feature, we could make sure the Status community (and user communities) can keep growing with actual active users.
Admins could send an announcement before doing it using @everyone to warn people that they are gonna use that feature and leave them some time to send an emoji reaction so that they don’t get kicked (for example if if they are only lurkers).

We don’t have to implement it straight away, but we need to think about it before too long, because once the community reaches 10K users, new users will just be automatically rejected.

As for the time to implement, I don’t think it would be too difficult, we already have all the tools in place in terms of admin messages that get sent to the control node. If we want to make it iterative, we could even make it only available for the control node side at first.
The query itself if pretty simple to implement and then it’s only about sending the updated community once the members are removed, which is something we already have in place.

So IMO, it could be implemented in less than a week. Maybe 2 weeks if we include the user stories creation, design, implementation and testing.

1 Like

Copying the discussion between Jen and me:

hydrojen Aujourd’hui à 14:49

Agree, except we’d need a way to exclude certain token holders ideally. And this would ideally be part of the wished for logs because we will have folks asking eventually why they were removed and we have no way currently to track if it’s for a reason or inactivity,

Jo Aujourd’hui à 14:51

Good point. Maybe we need to do the admin logs first

As for excluding token holders, it’s way more work, as it would need UI changes and more backend code to verify who owns what etc. I’d propose to do it iteratively with only the dates at first.

hydrojen Aujourd’hui à 14:55

Can we get a list to review once the dates are selected before confirming? I’d want to verify I’m not removing staff essentially. One could argue should be active but some roles aren’t needed in app as much or CCs from other projects, don’t want to undo all the permissions.

Jo Aujourd’hui à 14:58

Yes that’s a good idea. I actually thought of that when I imagined the feature when I was unable to sleep because of jetlag, but I forgot about it when writing the proposal So, yes it’s doable and shouldn’t be too hard and indeed, it’s necessary to do before, because it’s such a destructive action, a dry run is necessary.

i like this!

just one thing to note is that the @ everyone tag isnt working yet as a push notification on mobile. would be nice to get this implemented together, because push notifications are probably the most effective way to get people active on the app again. this also solidifies justification to remove if they wont even reactivate after that.

1 Like

The practical solution proposed here provides a good lens to approach large group scalability design.

The issue here is that the user trace data, ie, the residual data that an inactive user leave on the system, is large as it is included in community description messages, and is more than just a key: it includes profile image, socials. See Napkin math for Community description message sizes - HackMD.

When designing scalable group, one needs to review the cost of every inactive user in said group.
In the case of Waku, the cost is low as a node that is offline does not inject new data in the system nor do they take more connection slots.

However, we can see that for communities, it is large.
As well as private groups for that matter. For each (inactive) member in a private group, a message is sent to its members even tho they will not read it; in private groups, we don’t have one encryption channel for all members, but one per member; when sending a message to a group of 10 people, 10 messages are sent, potentially more if members have several devices paired.

A different approach is to reduced the trace data by limiting to authorisation data (I am allow to write here) and make the social layer more ephemeral, as proposed here:

The list could then be constructed from member’s messages.

Where members information (nickname, profile picture, social) is sent only when member are active.

The product downside is that Alice may not access Bob’s information if Bob hasn’t started their app since Alice joined the group - but is it really an issue?

I need to correct you here: what is included in the community description message itself is just the key and the role(s) of the member.
The images, name, etc. are added by the app layer to send to the client.

You can see it here:

(RevealedAccounts is deprecated so won’t be there much longer)

However, the amount of members does have an exponential impact on the community description size, because if all your channels are private, then you will have a certain number of members times the number of private channels being repeated.

Apart from the bandwidth cost, those members have a cost in terms of provider computation, since the control node needs to periodically check if they own the right tokens.

This is 100% true though.

This is kinda already the case. Like I said, the community description does not contain this info.
The clients must construct it themselves. How that works is that when you encounter another user for the same time, we save their information in the contacts database table. We then have their info.
What happens often is that someone joins a community, but never posts, so they appear on the member list, but your client never saw the user’s info, so you’ll see their name as a Three word name instead in the right bar.

I hope this clarifies some things.

read the linked vac discussion especially this part:

tbh im kind of uncomfortable with not being able to interact with any old members of a community, certainly if old means the 30-day waku store limit. being able to mention all users that ever entered your community is imo a crucial feature bc its the way to draw back members to your community every once in a while when you have something interesting. this might then lead such members to explore other features of the app while online if they havent opened it for a while. are we sure there isnt any solution that can keep mentions for old users intact? i really do see the total pool of users that ever joined as a valuable resource even if not recently active

1 Like

Thanks for the clarification/correction!

Good to know! This demonstrate another scalability weakness in the current protocol. Will leave it off scope for now.

Excellent to know, so in the context of my initial proposal, the idea is that you would not have a list of members, but instead, the member by being able to encrypt messages in the community would manifest its presence.

Meaning that as long as the encryption layer allows you to properly manage your members, and is scalable, then you could proceed by removing the growing list.
Very theoretical at the moment, but would be good to review once efforts such as de-MLS are more mature.


Keen to get your insight, again, this is all very theoretical right now.

In this idea, you would not be able to interact with an old member of the community if your app instance did not see any message from this member, ever.

Ah, that’s different here.

Because having an @everyone tag does not mean you have to know details about every individual user. Having such a feature only mean that when the app receives a message in a community that has @everyone in it, then it gives a notification to the user.

Depends how you want to exploit the resource. Also note that the community owner would like have information of all users, as every user would ahve contacted their node to join the community in the first place.

I am talking about re-broadcasting the information to users that join later.

do i still get the member data if i import the archive data from the community history torrent or even codex? as long as there is some option to archive the ‘lore’ of a community i think that would be ok

if this is the case then that makes the importance of long term storage either through torrents or codex on both mobile and desktop that much more important imo. i think many users especially on mobile right now join status and status inu and only see the few messages from the past 30 days and then think its all ded. i cry everytiem when i know new mobile users only see a fraction if anything of the glorious meme channel of status inu

seeing old members is maybe slightly less important than message history but still could in a few cases impact the lore of your community for example if some celebrity popped up for a day or so long ago. if their profile data could be fetched through the message data in the archive i guess you captured the most important one of such possible scenarios, namely the one where they actually said something

would be better tho if all member profiles including those that didnt say anything would be backed up in the torrent or on codex

yeah i guess in most cases it makes sense that only admins can send @everyone tags and the rest can still use the same functionality for active members anyway. it would then only be a ‘special power’ for admins to activate old inactive members because others wouldnt be able to. and if its true that new members can also reach old members in case of an available community history torrent, then we basically have all current functionality available behind the chs toggle in the community settings :+1:

1 Like

Not really what I am saying. it does matter who can use @everyone, but how @everyone functions. What I am saying is that you dont need the list of members to have a @everyone tag feature.

Can you please elaborate?

What does “activating an old member” mean?

ah sorry was going off an implication of what you were saying. iiuc then @everyone is like a one-to-many thing, everyone tagged just knows theyre tagged but doesnt necessarily know the full list of people being tagged. and then i thought yeah for this specific feature most of the time even on discord its mostly admins that have this privilege anyway (otherwise ppl might spam this mention). its not often that non-admins can use this ‘special power’ of tagging the whole channel at least in my limited experience

old member becomes a relative term without community member list in the description. the owner just has the complete list bc they accepted every member at some point. but members that recently joined can only see members that were active any time since ~30 days before they joined.

i see activating an old member as nothing else but mentioning them. for me at least push notifications are like the majority of the reason i open my social apps most of the time so i figured an occasional everyone tag, say in the form of an announcement, at least gives a good chance of having those old members opening the app again and maybe even post a message as a result.

so admins will have the ability to ‘activate’ the full list of members while recent members will only be able to do that with members theyve recently seen (who might not need that much activation to begin with that since theyre already active, but still better than nothing ofc).

To frame this again: I am leveraging this discussion to better understand expectations around Status Communities. I don’t expect any immediate action or change from this (apart from what @JoRain above suggested, sorry I hijacked the thread).

That the thing here. If a community member has not been opening the app for a while, meaning their details haven been pushed on the network. Then it means that the push notification will not reach them anyway.

If the app is still running in the background so they can receive notification, then their app would be broadcasting their details and then they would be visible.

I understand your concern to not being able to “bring back” old community member. But this is not impeded by the proposal I suggested. It is impeded by having privacy preserving push notifications.

Reading this again. Are you able to dig in more details?

If Alice joins a community Bob is already in, when would she share her bio to Bob?

Sure. This mechanism is not strictly for the Communities. However, the issue arises mostly in communities, because when you join one, you only receive the list of members as public keys.

To have access to their contact info like the display name and profile picture, there are two mechanisms.

The first one is the one that’s used when sending a contact request. We fetch from the store nodes to get the info. This usually works if the user has been active in the last 30 days.
We could use that method in the community, but it would be quite taxing for the store node and the user’s machine, because you’d need to make a request for every member of the community (as much as 10K), and if the user hasn’t been online in 30 days, it will fail, so it would retry on the next login (unless we implemented a flag).

The other mechanism is the most common and it is when receiving a message from a user, it contains the user’s info. It doesn’t have to be a one on one message. Any message including community messages works.

The Display name is in every message since it’s light.
The profile picture is “throttled” as to not send it each time since it’s heavy.
We have this function called shouldPublishChatIdentity. It’s what does the “throttling”.
The code says time.Now().Unix()-lastPublished > 24*60*60, so I guess users publish it every 24 hours.

I hope I was clear enough :smile:

2 Likes