I went through this process when I was designing the sync server for Digital Carrot.
In the end, I decided to just go with the simplest solution possible. In my case it's just a barebones Go gRPC service that uses an in memory channel to send notifications between connected clients.
The reality is that this simple Go server will scale up to about 1000 simultaneously connected customers on about 2gb of RAM. I don't expect to have more than that many paying customers, and if I do I can always just throw a bigger VM at the problem.
Engineers love to over complicate things in the name of infinite scalability, when in reality you can save a lot of time and effort by just understanding the scope of the actual problem you're trying to solve. Fingers crossed that this will become an issue for me some day, but until then most of us just don't need to worry about it!
I had a similar setup, scaled pretty well with some GOGC tuning. I had a small, simple "router" using channels https://github.com/urjitbhatia/gopipe and except for the per connection 16ish kb network overhead per socket, you can get away with a lot of performance with a small hand rolled service.