wtf( )unctionsystem design, drawn
← all problemsWebSocketsHard

The gateway stopped watching after the handshake

A chat product moved from polling to WebSockets and the request-rate limit at the edge went quiet — not because abuse stopped, but because the edge stopped being able to see it. Every protection the team had was written for requests, and there are no requests any more.

The fleet is drawn. Three things are missing, and each one is something that used to be somebody else's job.

  1. R1A client sending ten thousand messages a second down one already-open connection must be stopped. Whatever stops it has to be able to read individual messages on a connection that is already established, not merely decide whether to accept the connection in the first place.
  2. R2A message from someone on one server must reach everyone in that conversation, including the people whose connections are held by a different server. Every server holding a subscriber gets its own copy — a message must not be handed to one server and thereby taken away from the others.
  3. R3When a client reconnects it may land on any server, and that server must be able to recover what the client was subscribed to and how far it had read. Connection state therefore lives somewhere every server can query and somewhere that survives a server being replaced.
Compose what the upgrade took away. Tier 1 is what still counts and how a message crosses nodes, tier 2 is what a reconnecting client lands on.
Components — tap one, then tap a slot on the diagram
?A WebSocket is one HTTP request that never finishes. Every per-request thing you had happens exactly once, at the start, and never again.

Outside every boundary: Balancer (L4, passes the upgrade), Socket node B (holds connections), Clients (one socket each), Socket node A (holds connections), an empty slot for the what any server can look up on reconnect, tier 2, an empty slot for the counts messages on an open connection, tier 1, an empty slot for the one message, every server that needs it, tier 1 Connections: Clients holds an open connection to Balancer Balancer holds an open connection to Socket node A Balancer holds an open connection to Socket node B Socket node A calls what any server can look up on reconnect Socket node B calls what any server can look up on reconnect Socket node A calls counts messages on an open connection Socket node B calls counts messages on an open connection counts messages on an open connection publishes to one message, every server that needs it one message, every server that needs it publishes to Socket node A one message, every server that needs it publishes to Socket node B

BalancerL4, passes the upgrade
Socket node Bholds connections
Clientsone socket each
Socket node Aholds connections