List functional requirements for the system (Ask the chat bot for hints if stuck.)...
List non-functional requirements for the system...
Estimate the scale of the system you are going to design...
100 million total users
10 million daily active users (DAU)
5 million concurrent users per second
Num messages exchanged per day = 50 million.
Size of 1 message = 10 KB to 5MB(videos).
Total storage requirement = 50 million * 365 * 5MB = 20000 M * 5 MB = 100 PB per year
Define what APIs are expected from the system...
Send a message to a recipient
POST https://
{
id: (globally unique auto-incremented id to order messages)
from:
to:
content:
timestamp:
sha:
}
Get all messages for a user
GET https://
{
id:
from:
content:
timestamp:
sha:
},
{
}
.......
Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...
Message Schema (NoSQL)
Message Id From To Sha Content (text or link to image or video stored in Object Store)
User Table Schema (SQL)
User id Name Location ProfilePhoto Contacts Groups
Group (SQL)
Group Id Name Members ProfilePhoto
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...
Messaging Service: Responsible for sending and receiving real-time messages. User connects to it through web socket
Presence Service: Monitors user's online/offline status. Connection over Web Socket.
Auth: Authentication Service
Message Id Generator: A globally unique message id generator to maintain ordering across messages.
Encryption: Every message is encrypted before sending it to the recipient.
Message Queue: Message Queue of all outgoing messages. It is backed by a persistent KV store for all messages. Images and video are stored in the Object Store.
On reaching the message queue, a message is sent to the recipient's Messaging Service if recipient is online. Otherwise it is sent to the Push Notification Server to deliver a notification to the receiver.
Push Notification Service: 3rd party service which sends a notification of incoming messages to a user if user is offline.
Same approach is followed for Group messages. In this case, receiver is the 'group'.
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
Messaging Service: Responsible for sending and receiving real-time messages. User connects to it through web socket
Presence Service: Monitors user's online/offline status. Connection over Web Socket.
Auth: Authentication Service
Message Id Generator: A globally unique message id generator to maintain ordering across messages.
Encryption: Every message is encrypted before sending it to the recipient.
Message Queue: Message Queue of all outgoing messages. It is backed by a persistent KV store for all messages. Images and video are stored in the Object Store.
On reaching the message queue, a message is sent to the recipient's Messaging Service if recipient is online. Otherwise it is sent to the Push Notification Server to deliver a notification to the receiver.
Push Notification Service: 3rd party service which sends a notification of incoming messages to a user if user is offline.
Same approach is followed for Group messages. In this case, receiver is the 'group'.
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
Messaging and Presence Service have a stateful connection with the user. This avoids opening a new connection every time a new message is received or sent.
Authentication Server is stateless and can be scaled horizontally as required.
Explain any trade offs you have made and why you made certain tech choices...
Web socket connection is stateful so failure can cause the users to observe an interruption. However, it saves compute resources and is efficient as it avoids delay due to opening/closing connections.
Use shared message queue for all recipients instead of dedicated queue per user. This makes accessing messages for a given user inefficient but avoids copying a message multiple times for group messages.
Try to discuss as many failure scenarios/bottlenecks as possible.
Web socket connection is stateful so failure can cause the users to observe an interruption. However, it saves compute resources and is efficient as it avoids delay due to opening/closing connections.
Use shared message queue for all recipients instead of dedicated queue per user. This makes accessing messages for a given user inefficient but avoids copying a message multiple times for group messages.
Global unique message id generator is bottleneck.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?