IMO this is the number one reason why clients blow up relays sockets management systems - and with Go that means coroutines as well, that manage the pings - because client devs are web devs and are not familiar with this retardation called "websockets that flip from response to subscription when they receive an EOSE" and i doubt that is very scalable either
i'm sure other languages may be slightly more efficient at managing thousands of open sockets that are basically idle but it's not gonna be that big a difference, since the coroutine is 2kb and the socket has minimum 4kb buffer allocated, and that's just the read buffer, not counting all the state
it's just wrong to do request/response with sockets, not only is it extra initial overhead and a round trip, it's also those threads, and the ping pong waste, and the biggest waste is giving sockets to web devs who barely understand http requests