One thing I would like to say is that the development experience with Ruby/Rails is by far the best out of all of these languages. By FAR.
The way you can start a project in a second is amazing, the TDD experience and Rspec integration with Rails is simply mind blowing comparing to anything else.
Express might be 100% faster than Rails but it will take you 5 days just to get something running vs what you can do with Rails in a matter of minutes. From Authentication to Authorization and all the community around these.
Regarding the fast/slow it's simply bull-crarp, seriously. It DOES NOT matter for 99% of us. It simply doesn't.
Most of the slowness you are experiencing in Rails and Ruby apps is by doing poor engineering, not by Rails or Ruby itself. Big Surprise... If you query 1000 rows and bind them to the controller things will be slow.
There are things that are natively slower, JSON parsing and marshaling for example is one. It's much slower than Go for example but it's so much easier and for 99% of us, this is what matters.
I don't get the hate that Ruby and Rails are getting. Really don't.
> One thing I would like to say is that the development experience with Ruby/Rails is by far the best out of all of these languages. By FAR.
So far I find Rails very sane and well-thought-out, but I really, really dislike Ruby. I realize that's a personal preference issue, but it is what it is.
> The way you can start a project in a second is amazing
This seems pretty ubiquitous to me with "batteries included" frameworks. Rails doesn't have a huge leg up here over, say, CodeIgniter circa 2009.
> the TDD experience and Rspec integration with Rails is simply mind blowing comparing to anything else.
I very much like Rspec. One of Ruby's greatest strengths is the ability to define simple and semantically meaningful DSLs. Rspec is a great example of a good DSL.
> Regarding the fast/slow it's simply bull-crarp, seriously. It DOES NOT matter for 99% of us. It simply doesn't.
I agree 100%. Python is my preference, and not because it's lightning fast. It's fast enough that I'm almost never trying to improve performance, and when I am, my project has progressed to the point that it makes sense to scale horizontally instead of trying to make it fit into existing resource constraints.
> I don't get the hate that Ruby and Rails are getting. Really don't.
For me, it's because Ruby is just hard to grok. You have an object that's acting funny? Where is it defined? Here... here... here... some over here... Which one of those have been executed, and in what order? That sort of thing makes me want to pull my hair out.
I hear this almost every time Ruby is discussed, but I've been building rails apps pretty much exclusively since 2007 and I've only once experienced this problem and it was due to someone trying to make the most generic thing possible to solve a relatively simple problem incorrectly.
Can you point to a specific example? Is it in Ruby libraries? Is it in the application code you are working on? In Rails?
This is a classic case of weighing solutions against other solutions. When you do that the one with the most features or the fastest will always seem the best.
But, you need to weigh the solutions against your problem.
Your problem is time-to-market.
Your problem is development time.
Your problem is software reliability.
Your problem is finding great engineers to do great work.
When that's your problem. Ruby and Rails are great solutions. Not good. Great solutions.
Show me an express app that is as monolithic as some Rails apps and I will show you how Node.js halts to a crawl.
I am not going to try and answer these, it will be idiotic but all of these articles and some of the thrust behind leaving Ruby and these articles are just driven by the wrong reasons.
Most of the time a lot of that doesn't matter. Most apps have enough performance to handle their load, and if they can scale to 4-5x the users with minimal relative extra cost, it never will. But when you do need those extra bits, it helps a lot.
I've worked on a few node/c# apps where each ms counts... getting an extra 10k requests/second on a large server, or reducing latency by 10ms is a win. Not all things are equal. One should evaluate each use case.
To each their own... I only dabbled in RoR and wasn't much into it. Ruby seems like a great next gen Perl imho, and I thought that was cool. I just didn't like the everything in the box RoR experience. I lived through the early ASP.Net and didn't want a repeat of that. I like the lego blocks approach that Node and .Net Core are taking. I try to avoid many of the bigger pieces/sets.
This isn't to hate on Python or JS engineers; just that I don't see the same jump from JS to Python/Ruby that I see in dynamic to static languages (esp static langs with manual memory management).
Every time I've been involved in a situation where people complained about Rails being slow, this was the problem. It's not the ORM's fault if you're pulling every row from a table and iterating over them to find the record you want. It's not the framework's fault if you're pulling every row from a table to calculate the average value of a column. And it's not the language's fault if you're pulling every model entry into memory and chopping the array by hand to power pagination.
Rails doesn't save you from having to know SQL. No ORM can do that. The best an ORM can do is save you from having to actually write SQL most of the time.
You should compare Express to Sinatra, not to Rails.
Express is ridiculously easy to learn, btw. Coming from Flask (under Python), i learnt Express in 3 hours. Seriously.
Speed DOES (caps, emphasis) matters for many projects, in particular the projects that will go to real-life, to get massive use by consumers/common people. However, I do agree that for prototyping, startups, or simple apps that don't demand lots of performance, the speed of development under Ruby and its tools is a very important asset.
Agree with you, one shouldn't "hate" Ruby, no reason, really.
The point on the speed for me wasn't that speed as a whole doesn't matter. Speed in the language level doesn't matter.
If you do stupid shit with rails it will take 5.1 seconds and if you do stupid shit with Golang it will take 5.05 seconds. It simply doesn't matter all that much in the language/framework level for most of us.
For example: In my current job place we are using Flask for all microservices. One of the endpoints was very slow to respond and took 3 seconds. It ended up being a missing index in the DB.
Once fixed it's taking 20ms.
So, Is python slow because it's taking 20ms vs 12ms?
Honestly, if you do the same stupid shit with Go, it will take 0.51 seconds, according to many benchmarks out there.
> So, Is python slow because it's taking 20ms vs 12ms?
No, bad code is bad code. But on companies that have good programmers, sometimes you do hit a performance problem caused by the platform, and then you have to either a. throw more money (more servers, more CPU cores, more mem), or b. rewrite that section in other language. Actually, for example this is what some Python libraries do, for example Numpy has a lot of code actually implemented in C, not python.
The whole point is that CPU-bound web framework time is never the bottleneck for most companies. Golang doesn't change your database network latency.
If you DO hit the rare cpu bottleneck, you can offload it to services, cffi, whatever. It's so astonishingly rare that it doesn't make sense to optimize for most of the time.
Is RoR really getting much hate? Because I sure haven't seen that. Admittedly I usually don't really pay that much attention to random framework flaming, so I might not be the best to judge, but I feel like at least on HN RoR is still discussed in mostly positive tone. Besides "everyone" already knows that RoR is dog-slow (relatively), which I think balances the discussion to reasonable level.
Most of the companies I talk to today, don't choose Ruby. They mostly go with JS (Either express or Meteor or others).
The "Hate" for me is articles like this. Don't know if "Hate " is the right word.
I also believe there is a very viable long-term strategy of choosing a few of the current "hotness" stacks over your early career and learning them thoroughly. When the time comes that you're not wanting to chase the new thing so much and you start to experience age-related discrimination, you can focus on maintaining and improving existing projects written in those "old" stacks. There are lots of people out there today making good money doing "unsexy" work like maintaining Java/JSP or ASP Classic apps. In ten or twenty years, those jobs will be maintaining Rails, Django, and Laravel apps.
I am not comparing Express to Rails feature to feature (which if you read my other comments you understand I am against).
Anyway, welcome to HN!
It is great that as your first comment you say someone else's comment is silly.
All of our microservices are written in python and gateway to services are written in Node.JS.
Yes. Definitely. Absolutely. The users will perceive the difference. This is a slowdown of over 3X. If you're loading resources (in a variety of synchronous batches of asynchronous requests) for your web application, these slowdowns compound significantly.
Of course, the design of the web application plays a huge role, but assuming the worst (every user action triggers a request), a 3X slowdown is perceived by a variety of users.
> asynchronous requests
Because we don't live in a world where one user loads one page and then loads the next one (and if they do we should be talking about how your not using cached static content).
If I can do the work in 20ms, and it takes 100ms with framework overhead what happens when these start stacking up?
Not only do those things impact the user they impact your server... every ms that it has to maintain that connection, do work is one more ms that it isn't doing work for someone else.
EDIT: also, that paragraph is purely discussing the response times for producing the HTML document of a web application, not, say if you added 100ms lag to every JS response (which would compound, like you say).
edit: this is the best link I could find for now: http://highscalability.com/latency-everywhere-and-it-costs-y...
How about this: understand what the hell you're doing.
For 99% of the web, 531 requests a second is beyond what you need. Not everything on the web needs to respond to 7000+ requests a second. In fact most of it doesn't. Heck, most of it doesn't need to respond faster than 1 second. In my experience, most of the poor performance in Ruby web applications is caused by trying to shove too many operations into the same process and making all data "first class". This is probably in part because Rails for years didn't include a built-in jobs system.
The only thing "web-scale" means is that something serves HTTP requests through the web in a way that people find useful. If so, then any language that can create sockets is potentially web-scale, including COBOL. Beyond that requirement, there's no such thing as "web scale". All web companies like Facebook, Amazon, Twitter, Apple, etc., operate at different scales and adjust to their own needs accordingly.
As someone who's spent a lot of time scaling up ruby servers (I like to think I know what I'm doing), I can say it's not ideal for any high-scale applications for a few reasons:
1) It's hard to scale: Just look the thousands of stackflow posts on MRI garage collection tuning, unicorn forking, puma clusters and RoR performance to see that people struggle with it long before any huge scale. Other languages/frameworks are often 30x faster out of the box and cause fewer headaches when scaling up (we've been using GoLang lately). Ruby is easier to write and I love it for that, but much harder to scale. It takes more effort in the long run for high-scale apps.
2) The community tends to design for smaller scales. The ruby community is awesome, but as a result of focusing on lower traffic apps and single threaded/process web servers, a lot of the gems aren't designed for high throughput or concurrency. For example, ActiveRecord's connection pooling is often painful. Also, I found a pretty critical concurrency issue in the very popular DelayedJobs gem a few years back which had gone unnoticed for years.
3) MRI has performance issues: the GIL, slow GC, slow threading and other issues make it a slow language. It's fine for a lot of use cases, but try serving images, video or doing a lot of processing and you'll quickly hit its limits.
You absolutely can make Ruby work at huge scale, but it's much harder. I wouldn't recommend it if you hope/plan to require high-scale.
2) Rails has been thread safe since 2008. Ruby/Unicorn was serving some of the busiest sites on the internet in 2010. Go only went stable in 2012.
Connection pooling in other frameworks is usually even worse. Rails is the worst web framework, except for everything else.
delayed_job wasn't designed to be high throughput or threadsafe, but Resqueue and then Sidekiq certainly were.
3) The GIL also massively simplifies the Ruby internals for the core dev. Some platforms don't have performant hardware mutexes. Even dealing with OSX, Linux, Windows and *BSD is a nightmare.
The GC is actually really fast in Ruby 2.1+
Images shouldn't be served directly through Rails, even if dynamically generated. You're asking for a world of pain doing that.
I previously worked on a high-traffic mapping application where we generated the map tiles on the fly through a Rails app and served the images directly and we no scaling issues caused by Ruby/Rails but we did have plenty of CPU load from Imagemagick!
2) I said many gems, not Rails. Connection pooling in other frameworks is worlds better (GoLang's db package comes to mind). We're talking about now, not 2012.
3) Sure GIL is convenient when thinking about code, but the point is it makes high-scale hard. 2.1 GC is only fast by ruby standards. "Images shouldn't be served through rails" < exactly my point, other languages handle this with ease. If you are building a high-scale app you can choose 1 language+framework, or RoR AND another when things are big/hard/tough.
IMO, RoR (and Ruby in general) makes easy things easier, but hard things harder. A good tradeoff for some projects, but not big or high-scale ones.
What blows it out to 40x? Some sort of live image/sound manipulation?
If it was an inherent problem with Ruby, you wouldn't see such fantastic performance from nginx_mruby.
2) Sure, the Go connection pool is nice, but the Go ORMs are horrible as they try and work around the warts of the language. Everything's a trade-off, really. You give up terseness and flexibility for performance.
3) The GIL is definitely not convenient when thinking about code. Threads in Ruby still require you to write thread safe code. The GIL exists to make the _Ruby VM_ simpler. Otherwise you end up in the situation of Lua, where you have to re-initialize the VM in every thread and essentially have sub-interpreters, or you build something incredibly complex like the JVM.
The 2.1+ GC usually spends less than 1% of time in collection. That's fast by any language standard. The next step for Ruby will be a method JIT. There are two promising method JITs in development using LLVM as a backend.
Images shouldn't be served through a dynamic web app regardless of your language. They should be served directly via a web server to a cache/CDN, even if you're generating them on the fly like dynamically composed map tiles. People pan away. They pan back. You don't want to regenerate the tile.
I have read this number of times, now one Method JIT is shown, what is the other one?
> The majority of web applications handle far less than 1000 requests per second. I’d go as far as to say that most web application developers are employed by a company whose entire webapp does far less than 1000 requests/second. Most of them do less than 1000 requests/minute.
> When your application is big enough to be doing 20,000 RPM, you will have anywhere from a half-dozen to even fifty engineers, depending on your application’s domain. A single software engineer costs a company at least $10,000/month in employee benefits and salary. So we’re choosing our frameworks based on saving one-third of an engineer per month? And if that framework caused your development cycles to slow down by even one third of a mythical man-month, you’ve increased your costs, not decreased them. Choosing a web framework based on server costs is clearly a sucker’s game.
> What does web-scale even mean?
It's an old-ish meme, from this video making fun of MongoDB. 
To be fair, two points:
a. The benchmarks do rather easy stuff like fetching rows from SQL and then serving them. No heavier stuff (like compressing a file, etc).
b. On the provided benchmark, Ruby on Rails with Unicorn barely achieves 2000 request/sec.
And for good reason.
The problems that Github and Soundcloud have aren't related to their web front ends. Bandwidth, storage and a host of other issues are probably more front and center.
Twitter has these same problems but for a different set of reasons. Their web front ends are doing a hell of a lot more work relative to the amount of data coming and going. How big is a tweet vs a repo vs a song.
Yes they are all on the web but these three companies could not be more different.
> I've heard places convert from a Ruby stack to Java, and a lot of it was just to hide the fact that the programmers didn't know what the hell they were doing.
Why go from ruby to java? Because you want to invest in an ecosystem that is far more robust and far richer. You don't want a pile of ruby programers off in a corner doing their own thing with bunch of containers while you HAVE to hire java guys to deal with the large scale problems that organizations of a certain size face.
At the time twitter made this choice it was the ONLY choice to make. They didn't have a list of good options that we have today (Go, Scala, Haskle). The reality is that they would STILL probably choose java because it is still easier to find talent and it still has a richer background.
Lets make a comparison here... PHP vs RUBY, and lets talk about the devs. I am hard pressed to find a decent PHP dev who won't throw PHP under the bus (or out the window) when they get outside what it is good for. I am hard pressed to find a ruby dev who doesn't fully believe that the solution is always more ruby. There are plenty of good ruby devs (great ones in fact) who swear that ruby is the only way!
Rust brings a type-safe and memory-safe guarantees. Elixir brings concurrency and functional concepts that lead to clearer code. Even node.js has the benefit of ubiquity. Even if you want to debate those claims, those are perceived reasons for people adopting those platforms - just ask them. Having a more scalable and performant platform is just a nice bonus.
It is also misleading to think that performance impacts only the user experience. No, it drastically affects the developer experience too! Over the years the Ruby community has struggled with performance issues. Your application takes a long time to boot? Let's introduce a tool like Spring that works only half of the time. Your application cannot handle blocking requests? Let's push our whole design towards jobs. View rendering is slow? Let's add cache layers over cache layers (aka russian doll caching) and then good luck debugging cache expiration issues.
Even running tests is unnecessarily slow in Rails. When one test is querying the database, another test should be running. I am not talking about multi-core concurrency, just simple IO-based concurrency. Extra points if a language can give me CPU concurrency too!
Those are long term issues that impact the developer productivity and increase the maintenance burden on your teams. That's without taking into account other issues prominent in the Rails community, such as abusive use of monkey patching and global state. I moved away from Rails not because I wanted performance but because I wanted simplicity and long-term productivity.
There are much better alternatives today that build upon the strengths of Ruby and leaves behind it's weaknesses. As processors become more about multi-processing, languages that leverage that are going to gain popularity.
Sinatra is very popular...
But if you're a web developer, why WOULDNT you just develop your next net new project in Phoenix/Erlang instead of Rails/Ruby?
Phoenix has most of the development bedofits of Rails, yet way better performance and scalability.
Seems like a win-win. You get a Rails like development environment without any downside of perf.
"Just" is a terrible word we use far too frequently in the software industry.
Multiply "learn new language X and new framework Y and new idiomatic ways of doing things for Z" by the number of developers you work with. It's not a win-win and deserves consideration.
Compelling and valid temptation? Yes.
What is hard, is to use a purely functional language.
By design it is simple, because in my experience, the biggest obstacle to scaling properly is over-engineered code, especially premature optimizations that have the wrong guesses about what will need to scale.
Then hit them with multiple concurrent threads and move on.
I wish we wrote our stuff in a functional way like Elixir.
In my experience, it's much easier to forego TDD, only write important tests, and try to divide things out into separate projects where it makes sense. That way bugs can be quickly squashed and new features can be added quickly(very little time wasted learning a bunch of complex mechanisms), unique components of a larger system can be updated & rolled back pretty independently, and you get more value out of your testing than most tests I've seen in Rails monoliths(often foolishly testing Rails features themselves). This can be done through gems or even completely separate Rails/Node/whateva applications/APIs that communicate(remember, sockets are pretty fast). If you must have a monolith, at least consider what things should be "first class" and whether or not you can afford to have things get processed in the background. Async is easy these days.
I love what Rails has done for me and what it represents, but I've become disenchanted by the lack of deep thought that it's fostered in new developers, which includes me where I was not that long ago.
I think microservices become far less necessary when the monolith is structured in this way. I'd rather have a clean API to a subsystem exposed as a Python function call than as an HTTP endpoint with all the reliability and distributed systems issues that come along with that.
In 15 years of coding I've run into extremely few web dev projects that tree profiling to find the issue then caching hasn't solved.
"node.js is is the most bad-ass rock star tech to come out since Ruby On Rails"
"What was that last part again? I could have sworn you just said Lisp"
(Yes, performance and scalability are complicated. Different solutions will be appropriate for different situations.)
We're currently niggling over a few ms here, and a few there. Balancing the cost of adding more servers to distribute load. Migrating from colocation to cloud hosting in order to scale more seamlessly (iirc, over 150% growth yearly or more). Our SQL database has been a big bottleneck, moving heavy loads out of SQL and into more appropriate separate data stores.
Just because it's only an extra 100ms, doesn't mean it doesn't matter, as it's not the only link in the chain. I would never, for example use rails for an API service... it's too expensive on top of everything else.
Right now we have a fair amount of C#, a bit of Node, and may consider some go for future use in pieces. It comes down to picking the right things... It also depends on what/where you're using the technology.
And my favorite, Raverly (~7 mil user accounts), is done by two engineers (or was, not too long ago - it's hard to get numbers on these things). Two! Talk about developer efficiency.
"We use Go at Twitch for many of our busiest systems. Its simplicity, safety, performance, and readability make it a good tool for the problems we encounter with serving live video and chat to our millions of users..." - blog post a year ago.
Do your research before spreading old news.
I was not able to determine when Twitch began doing this, but seeing as their first major growth spurt was on launch, seems unlikely it was before they had to scale Rails to a substantial degree. I was also not able to determine what else they've switched over.
Old news is still relevant information, particularly when that news is "went from zero to ~10m on tech X".
Saying twitch "is in Rails" in 2017 is disingenuous to say the least.
...but Twitch still uses Ruby, and was still originally in Rails. It still stands as an example of scaling Rails, even if it no longer uses it.
for instance, raw php is really fast but apps like magento and wordpress slows it down to a crawl, more slower than a typical rails app.
depends per project but usually the slowness comes mostly from the abstraction with the db layer. where this means the latency to the db needs to be factored in to the benchmarks as well as to see if there are any lighter ORMs that can be used.
I'm afraid this is going to be more and more about which languages run on serverless platforms. Those companies decide which languages win.
Example: AWS Lambda is still Nodejs, Python and Java. We can hack about any language into it (I did with mruby), if we make Python or Nodejs exec it, but it's not worth the effort.
The benchmark provided (TechEmpower Benchmark) measure the amount of requests served, but these requests are for rather easy tasks like fetching data from a SQL database and serving it. Or doing JSON serialization.
Drop in a more alghoritmically-complex and/or general-purpose task (say, compress this file using GZIP before saving it on your server), and then you will feel the speed (or slowness) of your platform. And here perhaps you couln't hit the magical "1000 requests per second" benchmark.
Objectively, Ruby implementations (on the canonical Ruby MRI implementation) are slow. Sometimes even 100x slower than C.
Taking a deep look at these graphs, where 1x is C's performance under GCC:
Ruby MRI is typically 20x to 50x slower than C.
Looking at the graph is revelaing, but in any case, for other dynamically-typed, dynamically-linked languages, here are other typical figures for comparison (from the graph, relative to C/GCC, lower numbers better).
Ruby MRI* 20x to 50x
Python 3 Similar to Ruby MRI
Racket 6x to 12x
ECMAscript (Node.js/V8) 7x to 10x
Common Lisp (SBCL compiler) 2x to 5x
Haskell (GHC) 2x to 9x
Java (latest official JVM) 1.5x to 3x
Swift and Go similar to Java
C# (under .NET Core latest) similar to Java
Rust <1x to 2x
C++ (g++ compiler) equal to slightly slower than C
C under GCC 1x
At the end, for Ruby I would take the similar stance I would take with Python --- if I use it, it's because I like it. For example, I like using Python better than Js(under Node.js).
However if i was building a system that will demand performance, i'd look to other languages/implementations.
No, 1x is NOT C's performance under GCC.
As-it-says - "the fastest written in any of the programming languages" - and currently those fastest programs are written in C, C++, Chapel, Fortran, Rust.
It's much better to think of Ruby as a Smalltalk like high level language used to glue together lower level high performance building blocks.
Looking at things from this angle we see the typical Rails arrangement is actually business logic written in a high level language calling a bunch of native libraries eg. application server (Unicorn), HTTP parsing (Raygel parser), JSON parsing/generation (oj), HTML parsing/generation (nokogiri), DB client (pg).
It's also (apparently) why MRI has such a fast startup time compared to similar languages and other Ruby implementations.
You would need to compare "toy program" by "toy program", but for example, for the regex-redux program:
Bottom line is... MRI runtime is as memory hungry as a Java JVM runtime.
All of them have a rails framework clone :)
ruby needs, JIT, concurrency, and some crystal magic
The author is also way too pessimistic about newer stacks and is demonstrating a grumpy-old-fart-like attitude saying that "new stacks will find new ways to jam CPUs or I/O stacks". Might be true, might be not. It's not a fact.
I also get a vibe that the author exaggerates the problems with newer stacks. And it contains way too much assumptions in the case you switch stacks.
So he says that if you migrate to Phoenix or Node.JS, then:
(1) The load on the DB will not change. True, but Elixir has a cache directly inside the VM so the I/O costs for a _separate_ memcached server are almost fully eliminated right from the get go. (EDIT: in my not-so-big Elixir/Phoenix experience so far, Ecto is still faster than ActiveRecord; but I do still admit the DB load is pretty much the same.)
(2) 20k RPM doesn't mandate 50 engineers. I've been in a team managing an app with a 12k RPM with only two senior devs. We were just fine for the 2 years I've been there.
(3) New stacks slows down development. If you don't hire juniors, this is only true for the first 2-4 weeks. I've been fully onboarded in an umbrella Elixir app containing Phoenix and GraphQL endpoints, and a total of 6 apps, for 3 weeks. I surpassed my Rails development speed for 3 weeks. Very, very bogus assumption here.
Assuming that switching a stack means you do cargo-cult engineering is disrespectful. Sure he might have seen it 200 times, doesn't mean the whole world does it. As much as I love Elixir, I was honest with myself and had to write a few small microservices in Go, and I am glad that I did because it was a perfect fit.
I have a huge respect for Nate Berkopec and was following him closely for a while. He's a really awesome engineer. But that essay left me with a bitter taste of "my constultancy might be endangered, time to badmouth the new stacks". Why do I think so? Again, too many negative assumptions about the new stacks. No real argument, just negativity.
Does Phoenix pose its own WTF moments when you migrate from Rails (or any other framework)? Sure! It absolutely does. No tech stack is perfect. The end result however is increased developer productivity -- speaking about myself and apparently thousands more out there on the internet who claim the same -- and less server costs. And these both were measured over time.
If you want to use Rails, do so -- it is the perfect choice for a plethora of projects. But there is no need to badmouth alternatives especially if you don't have a case and your entire argument is comprised of negative assumptions about those alternatives.
I am disappointed with the author.