System Design শেখো
সব কেস স্টাডি

Chat App (WhatsApp) ডিজাইন

14 মিনিটintermediate
এক নজরে
  • WhatsApp-এর মূল হলো persistent WebSocket connection, যেটা দিয়ে real-time message push করা যায়।
  • Message-এর তিন অবস্থা — sent, delivered, read — এবং online presence ট্র্যাক করা মূল চ্যালেঞ্জ।
  • User offline থাকলে message queue-তে জমে থাকে আর push notification পাঠানো হয়, group chat-এ fan-out লাগে।

WhatsApp প্রতিদিন কোটি কোটি message handle করে — অথচ message প্রায় instant পৌঁছে যায়, আর সবুজ দুটো টিক দেখলেই বুঝি অন্যজন পড়ে ফেলেছে। এই simplicity-র পেছনে আছে চমৎকার একটা system design। চলো একজন senior engineer যেভাবে interview-তে ব্যাখ্যা করবে, সেভাবে ধাপে ধাপে দেখি।

১. সমস্যা বোঝা (Requirements)

প্রথমেই ঠিক করতে হবে আমরা ঠিক কী বানাচ্ছি। সব feature একসাথে নয় — মূল জিনিসগুলো ধরি।

Functional Requirements (কী কাজ করবে):

  • দুজন user-এর মধ্যে one-to-one message পাঠানো ও receive করা।
  • Message delivery status — sent, delivered, read (একটা টিক, দুটো টিক, নীল টিক)।
  • User online/offline presence দেখানো ("last seen" সহ)।
  • Group chat — একসাথে অনেকজনের সাথে কথা।
  • User offline থাকলে message জমা থাকবে, online হলে deliver হবে।
  • Offline user-কে push notification

Non-functional Requirements (কেমনভাবে কাজ করবে):

  • Low latency — message যেন এক সেকেন্ডের মধ্যে পৌঁছায়।
  • High availability — সার্ভিস সবসময় চালু থাকবে।
  • Consistency — message order ঠিক থাকবে, কোনো message হারাবে না।
  • Scalability — কোটি কোটি concurrent user সামলানো।
সহজ উদাহরণ

পুরোনো দিনের ডাকপিয়নের কথা ভাবো। তুমি চিঠি দিলে — সেটা "পাঠানো" হলো। ডাকপিয়ন বাড়িতে পৌঁছে দিল — "delivered"। প্রাপক চিঠি খুলে পড়ল — "read"। WhatsApp শুধু এই পুরো জিনিসটা মিলিসেকেন্ডে করে।

২. স্কেল আন্দাজ (Estimation)

হিসাব করলে বোঝা যায় system কত বড় হবে। আনুমানিক napkin math:

ধরি:
DAU (Daily Active Users)      = 50 কোটি = 500M
প্রতি user দিনে message        = 40 টি
মোট message/দিন               = 500M × 40 = 20 বিলিয়ন/দিন

QPS (Queries Per Second):
লেখা (write) QPS গড়           = 20B / 86400 ≈ 230,000 msg/sec
পিক সময় (×3)                  ≈ 700,000 msg/sec

Storage (ধরি প্রতি message ~300 bytes মেটাডাটাসহ):
প্রতিদিন                       = 20B × 300B = 6 TB/দিন
প্রতি বছর                      = 6 TB × 365 ≈ 2.2 PB/বছর

Concurrent connections:
পিক সময়ে online users         ≈ 50M – 100M
প্রতি server ~65k connection   → লাগবে ~1500+ connection server

মূল শিক্ষা: এখানে message storage বিশাল, আর সবচেয়ে বড় challenge হলো লক্ষ লক্ষ persistent connection একসাথে ধরে রাখা।

৩. API ডিজাইন

Real-time অংশটা WebSocket দিয়ে, আর বাকিগুলো সাধারণ REST দিয়ে।

// WebSocket দিয়ে real-time message (persistent connection)
WS  /connect?token=<jwt>          // connection খোলা

// WebSocket-এর ভেতর message events:
{ "type": "send_message", "to": "userB", "text": "...", "tempId": "..." }
{ "type": "message_ack", "messageId": "...", "status": "delivered" }
{ "type": "read_receipt", "messageId": "..." }
{ "type": "presence", "userId": "userB", "status": "online" }

// REST (এক-বারের কাজের জন্য)
POST /v1/messages                 // fallback message পাঠানো
GET  /v1/messages?chatId=&since=  // history/sync নেওয়া
POST /v1/groups                   // group তৈরি
GET  /v1/users/{id}/presence      // last seen

৪. ডেটা মডেল

প্রধান entity গুলো:

Table/Collectionমূল field
usersuser_id, name, phone, last_seen, public_key
messagesmessage_id, chat_id, sender_id, content, created_at, status
chatschat_id, type (single/group), member_ids
group_membersgroup_id, user_id, role, joined_at
inbox / message_queueuser_id, message_id (offline delivery-র জন্য)

SQL vs NoSQL choice: Message লেখার volume বিশাল (সেকেন্ডে লক্ষ লক্ষ write) এবং query pattern simple — "এই chat-এর message timeline দাও"। তাই messages-এর জন্য NoSQL (Cassandra/HBase) আদর্শ, যেখানে chat_id partition key আর created_at sort key হিসেবে রাখলে timeline read খুব দ্রুত হয় এবং horizontal scaling সহজ। অন্যদিকে user profile, group membership-এর মতো structured ও কম-পরিবর্তনশীল data-র জন্য SQL (PostgreSQL) ভালো।

৫. হাই-লেভেল ডিজাইন

মূল components:

  • Client (App): WebSocket connection ধরে রাখে।
  • Load Balancer: connection ছড়িয়ে দেয় servers-এ।
  • WebSocket / Chat Servers: persistent connection হোস্ট করে, message route করে।
  • Presence Service: কে online/offline ট্র্যাক করে (Redis-এ)।
  • Message Store (Cassandra): সব message persist করে।
  • Message Queue (Kafka): decouple + reliable delivery।
  • Push Notification Service: offline user-দের জন্য (APNs/FCM)।

Request flow (A থেকে B-কে message):

  1. User A তার Chat Server-এ WebSocket দিয়ে send_message পাঠায়।
  2. Server message-কে Message Store-এ persist করে এবং A-কে "sent" ack দেয়।
  3. Server Presence Service-কে জিজ্ঞেস করে B online কিনা ও কোন server-এ আছে।
  4. B online হলে — তার Chat Server-এ message route হয়, B পায়, B-র app "delivered" ack পাঠায় → A সবুজ দুটো টিক দেখে।
  5. B offline হলে — message তার inbox queue-তে থাকে, আর Push Notification যায়।
  6. B চ্যাট খুলে message পড়লে read receipt যায় → A নীল টিক দেখে।
Connection routing

লক্ষ লক্ষ server-এর মধ্যে B কোনটায় connected আছে — সেটা জানতে একটা session registry (যেমন Redis: user_id → server_id) রাখা হয়। তাই A-র server জানে message কোন server-এ পাঠাতে হবে।

৬. গভীরে (Deep Dive)

Persistent Connection ও WebSocket

WebSocket হলো একটা স্থায়ী, দুই-মুখী connection — একবার খুললে server-ও client-কে যেকোনো সময় data push করতে পারে। সাধারণ HTTP-তে client বারবার request করে জিজ্ঞেস করতে হতো "নতুন message আছে?" (polling) — যা অপচয়। WebSocket-এ server নিজেই তৎক্ষণাৎ push করে দেয়। কিন্তু সমস্যা: প্রতিটি connection memory খায় আর সবসময় খোলা থাকে, তাই একটা server-এর connection সংখ্যা সীমিত (~65k পোর্ট সীমা ছাড়িয়ে tuning করতে হয়)। তাই হাজার হাজার connection server লাগে।

Presence (Online/Offline)

Presence মানে কে এখন online। Naive approach — প্রতিজনের status সবাইকে broadcast — তা স্কেল করে না। বাস্তবে Redis-এ প্রতি user-এর last_heartbeat রাখা হয়; client প্রতি 10-30 সেকেন্ডে একটা heartbeat পাঠায়। নির্দিষ্ট সময়ের মধ্যে heartbeat না এলে user offline ধরা হয়। আর status update শুধু সেইসব user-কে পাঠানো হয় যারা ওই user-এর সাথে active চ্যাট খুলে রেখেছে — সবাইকে নয়।

Group Chat Fan-out

Fan-out মানে একটা message group-এর সব member-এর কাছে ছড়িয়ে দেওয়া। ছোট group (যেমন 200 জন) হলে server প্রতিটি online member-এর কাছে copy push করে, offline member-দের queue-তে রাখে। কিন্তু group খুব বড় হলে এই fan-out ভারী হয়ে যায় — তখন message একবার store করে member-রা চাইলে pull করে নেয় (fan-out-on-read), যা WhatsApp-এর সাধারণ ছোট group-এর তুলনায় আলাদা strategy।

সাবধান

সব member-কে synchronously fan-out করতে গেলে একজন slow/offline user পুরো request আটকে দিতে পারে। তাই fan-out সবসময় asynchronous — message queue (Kafka)-এ ফেলে দিয়ে background worker delivery সামলায়।

৭. বটলনেক ও স্কেলিং

  • Connection load: কোটি কোটি persistent connection — সমাধান হলো অনেক stateless gateway server + horizontal scaling, আর session registry দিয়ে routing।
  • Message storage: ক্রমাগত বাড়ছে — সমাধান chat_id দিয়ে sharding, আর পুরোনো message সস্তা cold storage-এ archive।
  • Hot groups: জনপ্রিয় বড় group — write hotspot তৈরি করে; queue + rate limiting + fan-out-on-read দিয়ে সামলানো।
  • Presence storm: লক্ষ user একসাথে online হলে presence update বন্যা; Redis cluster + শুধু relevant subscriber-দের update দিয়ে কমানো।
  • Push notifications: offline delivery-র জন্য FCM/APNs, যা decoupled queue থেকে চলে।
  • Reliability: Kafka দিয়ে at-least-once delivery নিশ্চিত, আর message-এ unique id দিয়ে duplicate বাদ দেওয়া (idempotency)।

End-to-end encryption সম্পর্কে: WhatsApp end-to-end encryption ব্যবহার করে (Signal Protocol) — message sender-এর ফোনে encrypt হয়, শুধু receiver-এর ফোনে decrypt হয়, server শুধু encrypted blob route করে, পড়তে পারে না। তাই public key user table-এ রাখা হয়।

৮. সারসংক্ষেপ

WhatsApp ডিজাইনের হৃদয় হলো — persistent WebSocket দিয়ে real-time delivery, Redis দিয়ে presence ও session routing, NoSQL দিয়ে বিশাল message storage, queue দিয়ে reliable asynchronous fan-out, আর offline user-দের জন্য push notification। delivery status (sent/delivered/read) আসে ack message-এর মাধ্যমে, আর encryption নিশ্চিত করে privacy।

টিপস

Interview-তে interviewer দেখতে চায় তুমি real-time delivery (WebSocket vs polling), offline handling, এবং fan-out trade-off নিয়ে স্পষ্ট ভাবতে পারো কিনা। "একটা message ঠিক কোন কোন ধাপে যায়" — এই flow পরিষ্কার বলতে পারলে অর্ধেক কাজ শেষ।

মিনি কুইজ

1. Real-time message push করার জন্য সবচেয়ে উপযুক্ত কোনটি?

2. User offline থাকলে message কোথায় থাকে?

3. Group chat-এ একটা message সব member-এর কাছে পৌঁছানোর প্রক্রিয়াকে কী বলে?