Bird
Raised Fist0
HLDsystem_design~10 mins

One-to-one messaging in HLD - Scalability & System Analysis

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Scalability Analysis - One-to-one messaging
Growth Table: One-to-one Messaging
UsersMessages/DayServer LoadDatabase LoadNetworkNotes
1001,000Single app server handles allSingle DB instance handles writes/readsLow bandwidth, no CDN neededSimple setup, no caching needed
10,000100,000Multiple app servers behind load balancerDB starts to see high write/read loadModerate bandwidth, consider cachingIntroduce Redis cache for recent messages
1,000,00010,000,000Hundreds of app servers, autoscalingDB bottleneck: read replicas, sharding neededHigh bandwidth, CDN for media filesUse message queues for delivery, partition users
100,000,0001,000,000,000Thousands of app servers, geo-distributedMulti-region DB clusters, advanced shardingVery high bandwidth, global CDNStrong consistency challenges, eventual consistency for some data
First Bottleneck

At small scale, the database is the first bottleneck because it must handle all message writes and reads. As users grow, the DB CPU and disk I/O get saturated. This slows down message delivery and retrieval.

Scaling Solutions
  • Horizontal scaling: Add more app servers behind a load balancer to handle concurrent connections.
  • Database read replicas: Offload read queries to replicas to reduce load on primary DB.
  • Sharding: Split user data across multiple database instances by user ID to distribute load.
  • Caching: Use Redis or Memcached to cache recent messages and user presence info.
  • Message queues: Use queues like Kafka or RabbitMQ to decouple message ingestion and delivery.
  • CDN: For media files (images, videos), use CDN to reduce bandwidth on origin servers.
  • Geo-distribution: Deploy servers and databases closer to users to reduce latency.
Back-of-Envelope Cost Analysis

Assuming 1 million users sending 10 messages/day each:

  • Messages per second (QPS): ~115 (10M messages / 86400 seconds)
  • Database writes: 115 QPS (each message is a write)
  • Database reads: 230 QPS (assuming 2 reads per message for delivery and retrieval)
  • Storage: 10M messages/day * 1KB/message = ~10GB/day
  • Network bandwidth: 10M messages/day * 1KB = ~120 KB/s peak
  • One DB instance can handle ~5,000 QPS, so single DB can handle this load but with little room for growth.
Interview Tip

Start by explaining the user scale and expected message volume. Identify the database as the first bottleneck. Discuss horizontal scaling of app servers, caching, and database read replicas. Then explain sharding and geo-distribution for large scale. Always justify why each solution fits the bottleneck.

Self Check

Your database handles 1000 QPS. Traffic grows 10x to 10,000 QPS. What do you do first?

Answer: Add read replicas to offload read queries and reduce load on the primary database. Also consider caching frequently accessed data to reduce DB hits.

Key Result
The database is the first bottleneck in one-to-one messaging as user and message volume grow. Scaling requires adding read replicas, caching, and sharding to distribute load, along with horizontal scaling of app servers and CDN for media.

Practice

(1/5)
1. What is the primary role of the server in a one-to-one messaging system?
easy
A. To allow users to send messages directly without any intermediary
B. To store all messages permanently without delivering them
C. To receive messages from the sender and deliver them to the receiver
D. To broadcast messages to all users in the system

Solution

  1. Step 1: Understand message flow in one-to-one messaging

    Messages are sent from one user to another through a server acting as an intermediary.
  2. Step 2: Identify server's role

    The server receives messages from the sender and forwards them to the intended receiver, ensuring delivery and possibly storing temporarily.
  3. Final Answer:

    To receive messages from the sender and deliver them to the receiver -> Option C
  4. Quick Check:

    Server acts as message relay = B [OK]
Hint: Server relays messages between users, not direct connection [OK]
Common Mistakes:
  • Thinking users connect directly without server
  • Assuming server only stores without forwarding
  • Confusing one-to-one with broadcast messaging
2. Which component is essential to ensure message privacy in a one-to-one messaging system?
easy
A. End-to-end encryption
B. Message queue
C. Load balancer
D. Caching layer

Solution

  1. Step 1: Identify privacy needs in messaging

    Privacy means only sender and receiver can read the message content.
  2. Step 2: Match privacy solution

    End-to-end encryption encrypts messages so only sender and receiver can decrypt them, ensuring privacy.
  3. Final Answer:

    End-to-end encryption -> Option A
  4. Quick Check:

    Privacy needs encryption = C [OK]
Hint: Privacy means encrypt messages end-to-end [OK]
Common Mistakes:
  • Confusing load balancer as privacy tool
  • Thinking caching secures messages
  • Assuming message queue provides privacy
3. Consider this simplified message flow code snippet for one-to-one messaging:
def send_message(sender, receiver, message):
    server.store_message(sender, receiver, message)
    server.deliver_message(receiver)

send_message('Alice', 'Bob', 'Hello')
What is the expected output or result of this code?
medium
A. Syntax error due to missing parameters
B. Message is delivered to Alice instead of Bob
C. Message is stored but never delivered
D. Message 'Hello' is stored and delivered to Bob

Solution

  1. Step 1: Analyze function calls

    The function stores the message from Alice to Bob, then delivers it to Bob.
  2. Step 2: Check message flow correctness

    Message is stored correctly and delivery is triggered for Bob, the intended receiver.
  3. Final Answer:

    Message 'Hello' is stored and delivered to Bob -> Option D
  4. Quick Check:

    Store then deliver to receiver = D [OK]
Hint: Store then deliver to receiver means message sent correctly [OK]
Common Mistakes:
  • Confusing sender and receiver in delivery
  • Assuming message is not delivered after storing
  • Thinking code has syntax errors
4. In a one-to-one messaging system, this code snippet causes messages to never reach the receiver:
def deliver_message(receiver, message):
    if receiver.is_online == False:
        return
    send_to_client(receiver, message)
What is the main issue causing message delivery failure?
medium
A. The function sends messages to the wrong user
B. Messages are dropped if receiver is offline without queuing
C. There is a syntax error in the if condition
D. The message variable is undefined

Solution

  1. Step 1: Understand delivery condition

    The function returns early if the receiver is offline, skipping delivery.
  2. Step 2: Identify missing handling

    Messages are not queued or stored for later delivery, so offline users never get messages.
  3. Final Answer:

    Messages are dropped if receiver is offline without queuing -> Option B
  4. Quick Check:

    Offline receiver drops messages = A [OK]
Hint: Offline users need message queue to avoid drops [OK]
Common Mistakes:
  • Thinking syntax error causes failure
  • Assuming wrong user receives message
  • Assuming offline messages are automatically queued
5. You are designing a scalable one-to-one messaging system for millions of users. Which approach best ensures message delivery even if the receiver is offline?
hard
A. Use a message queue to store undelivered messages and retry delivery when receiver is online
B. Drop messages if receiver is offline to save storage and bandwidth
C. Broadcast messages to all users and let receiver filter them
D. Send messages only when both users are online simultaneously

Solution

  1. Step 1: Understand offline delivery challenge

    Receivers may be offline, so messages must be stored to avoid loss.
  2. Step 2: Choose scalable solution

    Message queues store undelivered messages and retry delivery when receiver reconnects, ensuring reliability and scalability.
  3. Final Answer:

    Use a message queue to store undelivered messages and retry delivery when receiver is online -> Option A
  4. Quick Check:

    Queue undelivered messages for offline users = A [OK]
Hint: Queue messages for offline users to ensure delivery [OK]
Common Mistakes:
  • Dropping messages loses data
  • Broadcast wastes resources and breaks privacy
  • Requiring both online limits usability