Bird
Raised Fist0

Design a Video Calling System - WebRTC, Signaling Server, Media Server

HLDhardInterview freq: high
Choose your preparation mode4 modes available
🎯
Design a Video Calling System - WebRTC, Signaling Server, Media Server
45 min · senior
senior

You are tasked with designing a video calling system for a startup with 50 million daily active users. The system must support peer-to-peer and group calls with end-to-end encryption, maintain P99 latency under 200ms for signaling, and handle offline user scenarios gracefully. Calls can be 1:1 or multi-party with up to 10 participants. The system should scale globally and support web clients using WebRTC.

  • End-to-end encryption mandatory for all media streams and signaling messages
  • P99 signaling latency must be under 200ms to ensure call setup responsiveness
  • Offline users must receive missed call notifications and be able to join ongoing calls if possible
  • Support up to 10 participants per group call with media mixing or forwarding
  • Global scale with 50M DAU and peak concurrent calls up to 5M
  • WebRTC clients only (no native mobile SDKs in scope)
📋
Guided Steps
1/5
Step 1
Choosing the Signaling Architecture
How would you design the signaling layer to handle call setup and state synchronization at 50M DAU scale with P99 < 200ms latency?
💡 Hint
Consider WebSocket-based signaling with partitioning and state management for low latency and scalability.
Use a horizontally scalable WebSocket signaling server cluster behind a global load balancer (e.g., AWS ALB) with Redis Pub/Sub for cross-instance event propagation and sticky sessions for connection affinity.
Mid-level: Names WebSocket and Redis Pub/Sub for signaling. Senior: Explains sticky sessions to maintain connection affinity, Redis Pub/Sub for cross-instance event sync, and how partitioning reduces latency and load.
⚠️Common Wrong Answer
Using HTTP polling for signaling - causes excessive reconnections and high latency, collapsing under 50M DAU load.
Step 2
Media Server Selection and Role
What media server architecture would you choose to support group calls with up to 10 participants, and why?
💡 Hint
Consider SFU vs MCU trade-offs and how they impact bandwidth, latency, and scalability.
Use a Selective Forwarding Unit (SFU) like Janus or Jitsi Videobridge to forward media streams selectively, reducing server CPU load and client bandwidth compared to MCU.
Mid-level: Names SFU and basic forwarding. Senior: Explains SFU reduces transcoding overhead, supports scalable multi-party calls, and why MCU's transcoding is prohibitive at scale.
⚠️Common Wrong Answer
Using MCU for all calls - leads to high CPU usage and poor scalability at 5M concurrent calls.
Step 3
Ensuring End-to-End Encryption
How would you implement end-to-end encryption for media and signaling in this WebRTC system?
💡 Hint
Think about WebRTC's built-in encryption and how signaling messages can be secured end-to-end.
Leverage WebRTC's built-in DTLS-SRTP for media encryption and implement double ratchet or similar protocol at the application layer for signaling message encryption end-to-end, with keys exchanged out-of-band or via secure signaling channels.
Mid-level: Mentions DTLS-SRTP for media encryption. Senior: Details application-layer encryption for signaling, key management challenges, and how to prevent server access to plaintext signaling data.
⚠️Common Wrong Answer
Relying only on TLS for signaling and DTLS for media - signaling messages remain visible to servers, violating end-to-end encryption.
Step 4
Handling Offline Users and Missed Calls
How would you design the system to notify offline users of missed calls and allow them to join ongoing calls if possible?
💡 Hint
Consider persistent storage and push notification integration for offline delivery.
Use Kafka to persist signaling events with conversation_id as partition key for ordering, combined with Redis TTL-based presence tracking and push notification services (e.g., Firebase Cloud Messaging) to alert offline users.
Mid-level: Names Kafka for event persistence and push notifications. Senior: Explains Kafka partitioning by conversation_id for ordered replay, Redis TTL for presence detection, and how offline delivery integrates with signaling.
⚠️Common Wrong Answer
No offline handling or relying on client polling - leads to missed calls and poor user experience.
Step 5
API Design for Signaling Server
Design three core signaling server endpoints to support call setup, call state sync, and call teardown.
💡 Hint
Think about WebSocket message types or REST endpoints for offer/answer exchange, participant updates, and call termination acknowledgments.
Define WebSocket message types: 1) 'call.initiate' with SDP offer, 2) 'call.update' for participant join/leave and ICE candidates, 3) 'call.terminate' for call end with ACK response.
Mid-level: Lists basic endpoints or message types. Senior: Explains message payloads, sequencing, error handling, and how these support low-latency signaling and state consistency.
⚠️Common Wrong Answer
Using only REST endpoints with HTTP polling - increases latency and reduces real-time responsiveness.
🔌
API Design Challenge
Sketch 3 core REST or WebSocket endpoints for the signaling server that enable call setup, call state synchronization, and call teardown.
  • How does a client initiate a call and exchange SDP offers/answers?
  • How does a client synchronize call state changes like participant join/leave?
  • How does the system acknowledge call termination and resource cleanup?
📊
Scoring Rubric
▼ Show
Must Have - 60%
  • Use WebSocket signaling with sticky sessions and Redis Pub/Sub for low-latency event sync
  • Select SFU media server (Janus/Jitsi) for scalable multi-party video forwarding
  • Implement end-to-end encryption for media (DTLS-SRTP) and signaling (application-layer encryption)
  • Use Kafka with conversation_id partition key for ordered signaling event persistence
  • Design signaling APIs supporting call setup, state sync, and teardown with WebSocket message types
Good to Have - 30%
  • Presence tracking with Redis TTL to detect offline users
  • Push notifications integration for missed call alerts
  • Global load balancing to reduce latency
  • Partition signaling state to avoid cross-instance contention
Bonus - 10%
  • Explain key management challenges
✅
Model Answer
▼ Reveal

This design uses horizontally scalable WebSocket signaling servers with sticky sessions and Redis Pub/Sub to achieve P99 latency under 200ms at 50M DAU. Media forwarding is handled by SFU servers like Janus or Jitsi Videobridge to efficiently support up to 10 participants per call without transcoding overhead. End-to-end encryption is ensured by leveraging WebRTC's DTLS-SRTP for media and implementing application-layer double ratchet encryption for signaling messages. Kafka persists signaling events partitioned by conversation_id for ordered replay, enabling offline user support. Redis with TTL-based presence tracking detects offline users and triggers push notifications via Firebase Cloud Messaging. The signaling API uses WebSocket message types for call initiation, state synchronization, and teardown to maintain real-time responsiveness and state consistency.

  • Use AWS ALB for global load balancing to route clients to nearest signaling cluster
  • Implement WebSocket signaling servers with sticky sessions to maintain connection affinity
  • Use Redis Pub/Sub to synchronize signaling events across server instances
  • Select SFU architecture (Janus/Jitsi) to forward media streams selectively, avoiding transcoding overhead
  • Leverage WebRTC's DTLS-SRTP for media encryption and double ratchet protocol for signaling encryption
  • Persist signaling events in Kafka partitioned by conversation_id to guarantee ordered event replay
  • Track user presence with Redis TTL keys to detect offline users and trigger push notifications
  • Design signaling APIs as WebSocket message types for low-latency call setup, state sync, and teardown
  • WebSocket signaling servers with sticky sessions and Redis Pub/Sub for cross-instance event sync to meet P99 < 200ms latency
  • Janus or Jitsi Videobridge SFU for media forwarding to scale multi-party calls efficiently without transcoding overhead
  • WebRTC DTLS-SRTP for media encryption plus application-layer double ratchet protocol for signaling end-to-end encryption
  • Kafka with conversation_id partition key for ordered signaling event persistence and replay to support offline delivery
  • Redis with TTL-based presence tracking to detect offline users and trigger push notifications via Firebase Cloud Messaging
  • Global load balancers (e.g., AWS ALB) to route clients to nearest signaling server cluster for latency optimization
  • WebSocket message types for call initiation, state synchronization, and teardown to enable real-time signaling
  • Partitioning signaling state by conversation_id to ensure ordered event processing and reduce cross-shard coordination

Practice

(1/5)
1. If the quorum coordinator fails immediately after receiving write acknowledgments from a majority but before sending success to the client, what is the exact failure mode observed by the client?
medium
A. Client experiences a timeout and retries, risking duplicate writes
B. Client blocks indefinitely waiting for acknowledgment
C. Client receives duplicate success acknowledgments causing confusion
D. Client receives failure response despite successful write

Solution

  1. Step 1: Trace quorum coordinator failure after majority ack

    Coordinator crashes before responding, client waits but eventually times out.
  2. Step 2: Client retries write causing potential duplicates

    Client retries due to timeout; duplicates possible if write was committed.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Timeout triggers retry risking duplicate writes [check]
Hint: Coordinator crash before ack -> client timeout and retry risk [check]
Common Mistakes:
2. For a stock exchange system requiring low-latency order matching and high availability, which architecture is best suited to handle failover without losing in-flight orders?
medium
A. Use a distributed matching engine with partitioned order books per stock symbol and asynchronous replication
B. Use a single centralized matching engine with synchronous replication to a hot standby
C. Use multiple independent matching engines with eventual consistency and conflict resolution
D. Use a cloud-managed database with built-in failover and no dedicated matching engine

Solution

  1. Step 1: Analyze architecture requirements

    Low latency and high availability require partitioning to avoid bottlenecks and asynchronous replication to avoid blocking on failover.
  2. Step 2: Evaluate options

    Use a single centralized matching engine with synchronous replication to a hot standby blocks on synchronous replication causing latency; Use multiple independent matching engines with eventual consistency and conflict resolution risks conflicts and inconsistent order books; Use a cloud-managed database with built-in failover and no dedicated matching engine lacks dedicated matching engine causing latency and complexity.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Partitioned matching engine + async replication -> low latency + availability [check]
Hint: Partition and async replication for low latency failover [check]
Common Mistakes:
3. For a system ingesting high-frequency IoT sensor data with strict latency requirements, which architecture is better and why?
medium
A. Stream processing with windowed aggregations to provide near real-time metrics
B. Batch processing with hourly aggregation jobs to reduce storage load
C. Storing raw data only and running ad-hoc queries on demand
D. Using a relational database with indexing on timestamp for query speed

Solution

  1. Step 1: Analyze latency and ingestion frequency requirements

    High-frequency data with strict latency requires near real-time processing to avoid stale metrics.
  2. Step 2: Compare architectures

    Batch processing (A) introduces high latency unsuitable for real-time needs. Storing raw data only (C) delays insights and burdens query engines. Relational DBs (D) struggle with high write throughput and time-series data volume. Stream processing (B) supports continuous, low-latency windowed aggregations.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Stream processing enables low-latency, continuous aggregation [check]
Hint: Stream processing fits low-latency, high-frequency IoT data [check]
Common Mistakes:
4. At 10x scale, which component is most likely to fail first and why in Slack's real-time delivery system?
hard
A. Chat servers, because WebSocket connections are stateful and cannot be resharded easily
B. Presence service, because TTL cache invalidations overwhelm the system
C. Kafka brokers, because partition count cannot scale beyond a fixed limit
D. The database, because increased writes cause locking and slow queries

Solution

  1. Step 1: Identify stateful bottlenecks at scale

    Chat servers hold WebSocket connections in memory, which are stateful and tied to specific servers, limiting horizontal scaling.
  2. Step 2: Compare other components

    Databases can be sharded; Kafka scales with partitions; presence service caches can be distributed; chat servers' stateful connections are the hardest to shard.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Stateful WebSocket connections -> chat servers bottleneck at 10x scale [check]
Hint: Stateful WebSocket binds chat servers -> first bottleneck [check]
Common Mistakes:
5. At 10x scale, which component is most likely to fail first and why?
hard
A. The event store (Kafka) because partition count limits throughput and rebalancing causes downtime
B. The read model database because it cannot handle the increased query load
C. The command handler because synchronous validation blocks under high load
D. The Delivery Worker because it cannot keep up with event consumption rate

Solution

  1. Step 1: Analyze event store scaling constraints

    Kafka partitions limit throughput; increasing partitions requires rebalancing, causing temporary unavailability.
  2. Step 2: Compare other components

    Read model DB can be scaled horizontally; command handler is async; Delivery Worker scales with consumers.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Kafka partition limits and rebalancing -> first bottleneck at 10x scale [check]
Hint: Kafka partition limits -> first bottleneck at scale [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard