Instant message, groups and aggregate design

What kind of design (aggregates, etc) would be appropriate to create an instant message systems?
I see no problem to create a Group aggregate and message aggregate, but some data will have problem if stored in collection inside any aggreagte.

A user can block an indefinite number of users, different block can be imagined like:

  • Global block
  • Block per group chat
  • Block only for private message
  • Etc

But then, there is a need to store this information, different solution can be implemented but some will clearly have issues if have millions of users and someone starts to block thousands or even millions of users. Same problem will occur when having groups that can have millions of users.

Should we have one aggregate per user that store all blocked users, each type of block may be contained in different aggregate or one global, does not matter.

Should we inverse the logic of storing users within a group? -> Instead of having the list of user ids in the group aggregate, we can have an aggregate per user that list group ids that user is part of; This limit the issue of millions of users in one group but then we may have an issue when a user is part of millions of groups (not supposed to happen but no idea on business logic sometimes).

Another solution could be to have some aggregate like User, Group, Message, and when user wants to join a group, there is only a query issued to check if user is or is not already part of this group, if not then an event is published (not from an aggregate ). Of course there may be some concurrency issues where same event of joining/leaving/etc a group may be published but can be mitigated via some distributed lock, etc.
This way we have a read side that listen to group creation/join/etc, message send/etc and can then build a view of groups, users, messages, etc without having issues of millions since this is all stored in DB and queried appropriately via SQL queries.

How would Axon Framework handle millions/billions of aggregate of same type (Message) that are most of the time only created and almost never modified.
Is there any potential problems from the framework at some points?

Should Message aggregate not even exist, and we use same idea of groups join/leave/etc, where we only do some query to verify business logic then publish an event of “MessageSentEvent”? So when we want to modify a message, it queried (Axon query or DB query) and actual logic applied and new event sent to apply the changes (still not inside an aggregate).

What are your thoughts? Opinions?
How would you design an instant message system where millions of users could be part of it, with millions of messages sent every day, and millions of groups created/deleted, etc?


Anyone has ever made something similar?

Hi Yoann,

this is a typical modelling question, to which there is no simple answer. That most likely explains the lack of response from the community. My lack of response was purely based on (lack of) time ;-).
The only correct answer is “it depends”. In the end, this information needs to be in a view model where the system can check whether a sender is on the recipient’s “blocked list”.
Where the command ends up isn’t too important for this particular feature. That is much more around certain consistency guarantees that you might have with other commands being executed. You could even consider not using an aggregate at all and just publish an event directly each time a user decides to block another.

Hope this makes sense.

ok thanks.