Last month Scaledrone migrated all websocket servers from Node.js to Go. We are a push messaging company so using the best possible websocket solution is vital to us.
We started playing around with Go because the memory required per customer was very high. In the end we got more than we asked for as Go servers use a third of the memory that our Node.js servers did. In addition to the memory usage lowering, both response and connections times were reduced significantly.
Node.js vs Go
Ease of use
I found Node.js a much simpler platform to use, mainly because there is no worrying about concurrency. While Go does provide some elegant patterns for dealing with concurrency you still have to take it into consideration as if you were writing any other concurrent language.
Both platforms have pretty active and growing ecosystems but as Node.js has been around the block longer it boasts more than double the modules. On some occasions I found no open source packages for Go even though there were multiple alternatives for Node.js.
Image from modulecounts.com
Another thing I found bothersome were the generated GoDoc pages. They were ordinarily not as easy to understand as hand written Node.js GitHub readme pages and came with very few, if any, examples.
Both platforms have their strong suits. While I find Node.js more fun to use I cannot deny that migrating our most performance critical service to Go has given us a lot more breathing room.
I recommend Node.js for those who don’t have to deal with hundreds of thousands or millions of concurrent connections and Go for those who do.
Go has two very popular websocket packages. x/net/websocket which is bundled with Go itself and gorilla/websocket which is a third party package. We learned the hard way that x/net/websocket is missing a lot of features and not stable enough for production use. I recommend using gorilla/websocket.
pprof is an awesome tool to tracking memory leaks in Go. This made tracking leaks in Go much easier than in Node.js.