WhatsApp System Design

Introduction

In this blog, we are going to discuss the system design of popular chat application WhatsApp. This is a generic system design and could be used as a base for designing any chat application. We are going to focus on implementing some key features. If you haven’t already please check out the other blog on how-to tips to tackle system design.  Let’s get started!

Feature requirement

  • Direct Messaging
  • Last Seen and Message acknowledgment (Sent, Delivered and Read)
  • Media Support (Images/Videos)
  • Error Logging

If you like the following article I would suggest you to subscribe to my blogs.

Direct Messaging

If we have just two devices on the same network which need to transfer messages between each other then we need to know the address of both the devices and can exchange the message directly. But when the number of devices and the number of networks increases then it becomes increasingly difficult and we need to have a server in between that is responsible for receiving/sending the messages to appropriate clients.

Below is a high-level overview of the architecture where client A and client B want to exchange the message.

As you can see in the diagram there are two clients in the diagram Client A and Client B. Here Client A needs to send a message to Client B. It initiates a request to the server.  It needs to use a protocol for communication. Here we need to use a peer-to-peer communication protocol because the server needs to initiate a response and actually deliver a message to a client. Hence we can’t use HTTP connection which is a client to server protocol. We can use long polling or TCP connection with web sockets. The TCP connection with web sockets works really well for chat application because once the connection is established there’s very little header information that needs to be exchanged and the size of the message decreases significantly.

As soon as a user becomes online a new TCP connection is established. When the user sends the message it travels through the gateway. Gateway is responsible as an abstraction of security, reverse proxy, rate limiting, etc. Then the request goes to the load balancer which is responsible for distributing the load across multiple servers. The messaging server then checks in the database to which server the client B is connected to and forwards the request to client B.

There could be different scenarios when sending the message.

  • Client A is offline: In this scenario, the message which needs to be sent is stored on the device’s database(e.g. SQLite) until the device becomes online
  • Client B is offline: In this scenario, the message gets saved in the database. As soon as the client becomes online the messages are sent to the client.

Let’s take a deep dive into how the messaging server works.

As soon as the client is connected to the messaging server a new Process/Thread and a message queue are created for the client. This information is also stored in a table inside the database.  When a message from the sender arrives it is placed inside the message queue. This message gets picked up by the process and it checks the database if the receiver is connected and which process/thread is assigned. It then places this message into the sending queue for the receiver and the process for this receiver sends this message.

Last Seen & Message Acknowledgement

 

Whenever a client is performing any activity such as sending a message, opening a new message, uploading documents or making a phone call this recent activity along with the time stamp is recorded for the user. With each new activity, the timestamp for the user is updated. Whenever a user B wants to check the last seen of user A then it requests the database to get the timestamp of user A. If the timestamp is within the range current time – threshold value(e.g. 1 minute) then we can display the status as online else display the last seen as the timestamp of user A’s last activity timestamp.

 

WhatsApp supports 3 message acknowledgments: message sent, message delivered and message read.

As soon as the server thread processes the message from the received message queue it sends the client that the server received the message. When the receiver receives the message or reads the message a new request is sent to the server which then updates the sender about the status of the message.

Multimedia Support

In a chat messaging system it’s common to share images, videos, and file attachments. These could be a long-running process and should be separated into another microservice that could handle such requests. As shown in the diagram below the there’s another multimedia server that handles these types of file sharing requests. The client initiates an HTTP request to the Multimedia server. The multimedia server checks if the receiving client B is online. If yes then it sends the hash of the file to client B. The client B uses this hash to download the file. 

 

If the client B is offline then the file is stored inside a secure cloud storage. As soon as the client B comes online it receives the hash and fetches the files from the cloud. To make this file sharing faster we could use a CDN. A CDN stands for Content Delivery Network which caches the information geographically near the client’s location to reduce the latency and increase the download speed.

Error Logs

Making a chat application robust is really important. Especially when there are millions of users connected to the servers and millions of events occurring throughout the day. Getting notified about errors in real-time is critical and a challenge. 

 

We can use elastic search for searching through error logs and faster access. All the server error events pass through a normalizer for stripping down unnecessary information and recording what’s needed. This information is constantly fed into an Elastic search cluster. The Logstash gives an overview of the events occurring throughout the servers and we use Kibana for visualizing the data and prepare reports.