The same number of workers (that required 12 GB in Ruby) now requires just 5 MB of memory.
Not that I don't approve of pro-Go articles, but doesn't this maybe indicate that something was wrong or inefficient in the Ruby implementation?
The same number of workers (that required 12 GB in Ruby) now requires just 5 MB of memory.
Not that I don't approve of pro-Go articles, but doesn't this maybe indicate that something was wrong or inefficient in the Ruby implementation?
Our takeway was that the (Rails) monolith model tends to put a lot of things into one process space. Controlling library loads can be a chore.
I could have rebuilt in Ruby and that was my first thought but deploying and maintaining Ruby apps are lot harder then you can imagine. I didn't like idea of maintaining lots of small ruby apps. Once you deploy single Go application, you might not want to deploy another Ruby app.
We do a lot of non-Rails Ruby-work and did implement Microservice-Architectures in it and found it rather unproblematic. The trick is not to start with a full-stack and build down, but to start with a small kernel of an app, deploy it, add something, deploy it, iterate, iterate, iterate.
I don't use the Ruby stack, but if forking happens after loading libraries, this is not true, since most UNIXes (such as Linux) use COW memory pages when forking. So, it may appear that you use N times the memory of a single process, but most of their memory pages are shared.
See fork(2).
Only in recent Ruby versions is that not a problem (and was changed for exactly that reason).
But yes, your memory report might be read wrong.
I haven't done a thorough or systematic comparison, but I'd expect slightly slimmer but similar results with Sinatra apps given the 80MB figures you quote above, the rails processes were around 120MB on average, Go 6-10MB and scales without extra processes. Obviously the smaller the framework you load for each process, the less memory you're going to use, but there are also architectural differences in the languages which seem to add up to significant memory usage in the case of Ruby.
Because to scale ruby you'll typically add more processes, and to scale go you'll just let it start another thread (the http server does this for you), that difference adds up to a significant difference when you have a lot of traffic.
That's not to say that Ruby is impossible to scale and I love Ruby the language, but it is a bit slower and a bit more memory intensive than Go.
Also, you can move to JRuby if you want a one-process/threaded model, which will get memory-conservative very quick. A JRuby thread will quickly get you into the ranges that you quote for go + the base cost of the JVM.
Point being that memory comparison even in the Ruby/Rails space are incredibly problematic, often influenced by the runtime (and heavily so). Still, the discussion is incredibly simplistic (for example by assuming that you are running unicorn/fork).
If a discussion about memory issues does not include an exact reference to the runtime and implementation of the system used, I would consider it void immediately.
Same for Go.