HavenDOCS
Back to Home

WebSocket Matchmaking & Signaling

To support 10K+ concurrent users with zero database overhead, Haven uses a dedicated Node.js WebSocket Server.

Why Not Supabase Realtime?

Initially, Haven used Supabase Realtime (Phoenix Channels) for matching. This had several bottlenecks:

  • Max Connections: Limited by Supabase tier (200 in free tier).
  • Matching Latency: Required PostgreSQL waiting_queue polling or RPC calls.
  • Race coached: Advisory locks were needed, which can become a bottleneck under high load.

New Architecture (2026)

  • Microservice: A specialized Node.js server (separate from the Next.js app).
  • In-Memory Logic: Uses a Map-based waitingQueue to store active WebSocket connections.
  • Atomic Matching:
    • Map<WebSocket, User>: Stores waiting users.
    • match_found: Instantly pairs two users when both are available.
    • Zero Database Load: The match happens entirely in memory. Only the final chat_session is written to the database.

Key Features

  1. In-Memory Queueing:

    • buddies_first: Prioritizes matching users who are already connected (mutual friends).
    • global: Matches with anybody in the pool.
  2. WebRTC Signaling Proxy:

    • The WS Server acts as a signal relay between two matched peers.
    • Handles offer, answer, and ice-candidate messages.
  3. Automatic Reconnection:

    • Clients use exponential backoff to handle network flickers.
    • Heartbeat keeps the connection alive on platforms like Render or Fly.io.

WS Message Types

  • join_queue: Notifies the server that the user is ready.
  • match_found: Server notifies two users they have been paired.
  • signal: Relay WebRTC metadata between peers.
  • partner_left: Instant notification if a peer disconnects.
  • report_user: Trigger a fast-block in memory and log to the database.

[!TIP] Performance: Matches are typically performed in <5ms after the second user joins the queue.

Source Code

The matchmaking server is located in the matchmaking-server/ directory.

  • server.ts: Handles the main WebSocket logic.
  • newrelic.js: Monitoring for real-time traffic.