A naive implementation uses HTTP polling: the client sends a GET request every second asking “any new messages?” This generates billions of unnecessary requests per second. Most of those requests return empty responses. The server cannot push messages — the client must always ask. Latency is bounded by the polling interval.
HTTP long-polling (holding the request open until a message arrives) improves latency but still requires re-establishing a connection after each message. At billions of concurrent users, the connection setup overhead is prohibitive.
WebSockets solve the push problem: a persistent bidirectional TCP connection that allows both client and server to send data at any time without re-establishing the connection.