12 ms·
I’m also a big fan of rails, but I’ve experienced a lot of problems scaling it. A lot of the problems ultimately came down to the simple fact that Ruby is reall
by ffdjjjffjj 6y ago
I’m also a big fan of rails, but I’ve experienced a lot of problems scaling it. A lot of the problems ultimately came down to the simple fact that Ruby is really, really slow. At a certain scale you end up forced to develop infrastructure on a different stack to keep up with the CPU load. I never ran into that so quickly when building similar systems with java, go, and C#.
I wanna say something nice about rails too so I’ll say I have never seen a team so quickly deliver high quality web app features than a well oiled rails team. It’s something to behold.
- erikrothoff 6y agoCurious what part of Rails you didn’t find scalable? Our Rails frontend servers run on cheap VMs that are easily scaled horizontally.
- awestroke 6y agoScaling horizontally is not cheap. A faster language needs fewer replicas.
- erikrothoff 6y agoReally? Our frontend servers handle 50 rps and cost $20 each and are nowhere near peak utilization. If anything ever needs scaling its the database. What level of traffic are you talking about?
- tutfbhuf 6y agoFor example a newspaper with customizable content, 1 petabyte (70% video) per month and avg. 2k request per second.
- erikrothoff 6y agoI don’t want to second guess technical decisions I know nothing about but: no, Rails shouldn’t be streaming video. But 2k requests per second with mostly text content being shuffled around sounds absolutely doable with Rails. The cost benefit of easier development should definitely not be understated as well. But that being said, the primary driver for tools should be what the developers know and ease of access finding developers who know this technology. If the city you work in mostly has PHP developers, PHP is a great choice. Similar for Java, Haskell, Lisp, etc. My point is that the tool ”Rails” definitely is adequate for this problem (minus streaming video...). Look at Shopify, Github or any other massive Rails app
- cambalache 6y ago> I don’t want to second guess technical decisions I know nothing about but: no, Rails shouldn’t be streaming video. Yeah, if you are serving video at that rate, there are plenty of CDNs to work with, why would you submit your app engine to that.
- kazinator 6y agoIf a Rails back-end streamed video, there wouldn't literally be a loop written in Ruby shoving bytes back and forth stored in Ruby arrays or buffers. It would be farmed off to something appropriate. You wouldn't necessarily want that machine to be doing it, using any middleware.
- the-dude 6y agoWhich newspaper is hitting 2k req/s ?
- tutfbhuf 6y agoFor example: https://stackoverflow.com/a/373188 https://stackoverflow.com/a/373188 > Wikipedia seems to be 30000 to 70000 [requests] per second spread over 300 servers So 2k is not unusual for bigger news sites, that may or may not employ a (few) rails team(s).
- thirdusername 6y agoThat’s only 100-250rps per server, that’s really not very hard in any framework. Financial exchanges are doing 100,000rps of transactions per sever. That’s hard.
- treis 6y agoCompared with developer time servers are cheap. Even for a single developer being 10% quicker at development equates to dozens to a hundred servers.
- marsdepinski 6y agoYet somehow the popular industry pattern adopted by the industry is to waste ad much developer time as possible.
- stepbeek 6y agoI never understood this until I was self-employed. I now feel this in my soul.
- nitrogen 6y agoRails handled Black Friday and Cyber Monday traffic for an ecommerce company I used to work for just fine. If you are making money, it's worth the cost of 50 lowend VPSes autoscaled (we could have done with a lot less, too). If we were using Java it would have taken us three times the people and four times as long to build the site, and we all would have been laid off.
- rualca 6y ago> Rails handled Black Friday and Cyber Monday traffic for an ecommerce company I used to work for just fine. That says nothing about the added cost of running inefficient services, which require additional nodes to serve the same requests and thus increase operational cost and also risk to perform the same service.
- marsdepinski 6y agoNot if you hired better people.
- FpUser 6y agoFor rare events this concept works fine. For large sustained loads using more language/runtime could save a fortune.
- erikrothoff 6y agoDo you have a real world example? For example, what are you spending on a single app server? And how many RPS should it handle?
- jon-wood 6y agoRails is great if what you’ve got is read-mostly cachable content being served up. In an environment with high rates of incoming data, most of which can’t be reliably cached, things get more interesting and you start needing to scale horizontally a lot more and leaning on the database.
- dwheeler 6y agoHave you used fragment caching (in "Russian Doll" style)? In my experience, that's the key to making Rails applications fast. Ruby is slow, so there are definitely situations where it's not a good choice, but in many "basic applications" caching makes that irrelevant. Language speed is irrelevant when you don't run much code :-).
- prh8 6y agoCPU load being the ceiling in Rails is typically the sign of sloppy development. Most well done apps it will be the database.
- jes5199 6y agoit seems like a lot of my career has been optimizing SQL queries in Rails apps... which is often just adding the correct indexes. Kind of a lot of Rails devs just don’t know to do that
- forgingahead 6y agoSounds like a great and valuable blog post to help teach them the right heuristics!
- jbverschoor 6y agoand java devs and c++ devs and php devs and python devs etc. etc.
- JohnBooty 6y agoYes, this matches my experience. I've been doing Rails full-time for about 6 years and any "slowness" has been the result of some problem, not Rails itself. 99% of the time this is an uncached n+1 query situation, or some beastly slow database operation that needs to be moved to background processing, things that would be problems in any framework or even some sort of bare-metal asm solution that nonetheless relies upon an external storage layer. =) In a CRUD app the Rails layer should be extremely thin and the storage layer(s) should be doing nearly all of the heavy lifting. There is a level of traffic at which even a "properly" thin Rails layer becomes the bottleneck, relative to many other frameworks. TechEmpower benchmarks suggest it is around 2,500 requests per second in their "multiple queries" benchmark. In a more real-world scenario that might be 1,000 req/sec or less. https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=query https://www.techempower.com/benchmarks/#section=data-r19&hw=... If one is attempting to serve more requests than this per minute then yes, perhaps Rails is the bottleneck. Admittedly, Rails' large memory consumption relative to other frameworks means it can be tough (well, technically easy, but expensive) to scale horizontally at this point.
- dasil003 6y agoThis very much depends on the use case. If you are truly CPU-bound than yes, ruby is a bad choice. Similarly, if you are IO-bound or otherwise need a lot of concurrency ruby is not great. I also think it's problematic for large code bases with hundreds of developers. However, there is a huge swath of web apps and APIs that just need to pull a bit of data from a DB or two, munge it together and send it to the client. Rails is perfectly horizontally scalable and plenty fast for this even at scale given Amdahl's law. That said, there are definitely some self-inflicted wounds people run into here. Of course there are the oft-cited expert beginner problems like n+1 queries and missing indices, but there's a more subtle issue as well: ActiveRecord itself is so convenient that it discourages writing baseline efficient code even when you need it. Basically any time you need to process a medium to large amount of data, ActiveRecord acts like a sort of super boxed type (to use Java terminology) adding a huge amount of overhead. Yes it's true that ruby doesn't even have true primitive types that can achieve the performance of Go or Java, but often times ruby primitives are plenty fast, you just have to be willing to write a bit of extra code, and ActiveRecord as an ORM has plenty of escape hatches at various levels of granularity to facilitate this (eg. pluck, find_by_sql, update_all, execute, etc).
- ryanbrunner 6y agoI definitely agree that when writing Rails at scale, it's extremely important to view ActiveRecord as just another tool in the toolbox, and not always effective for every use case. I've worked in places that had a dogmatic aversion to ever writing raw SQL, and to a one they always suffered for it in performance sensitive code. At the places who did handle this well, the "high-performance code" that needs to be hand-tuned SQL is usually much smaller than you think (a few queries here and there), and ActiveRecord is still great for your simple queries or for smallish tables.
- Lio 6y agoCould you go into more detail about what you see as issues with IO bound tasks? My understanding is that MRI Ruby provides non-block IO operations if you wrap them in a thread and that it is only CPU bound tasks that are blocked by the GVL. Is there some other issue related to that? (JRuby provides fully multi-threading for cpu bound tasks without GVL).
- stanislavb 6y ago"the simple fact that Ruby is really, really slow"... it's that slow that Shopify and Stripe don't mind building their global scale products in Ruby.
- Nextgrid 6y agoSlowness seems to be an overblown issue when it comes to the backend. Hardware is cheap compared to developers and app servers scale horizontally by default; if a language is actually slow but otherwise provides good productivity it's almost always cheaper to throw more hardware at it than move to a "faster" language (there's a reason we don't typically write web apps in C).
- adrianpike 6y agoWould love to hear what you're doing that's got Ruby pegging the CPU. I've ran a few rather large Rails deployments over the years and it's rare to crush the app tier first, so I wonder if there's something unique here that we can make Rails better at.
- joshmn 6y agoRails makes it really easy to do something 10 different ways to get the same result. Unfortunately, most of which aren't the most performant way. In my 10 years of building Rails apps of all different sizes, and seeing some very mature apps in production, this is the most common culprit I've seen. I currently work on a rather large Rails app for a site that most of us here use. A common pattern for our performance pitfalls are things like this: Tag.all.map(&:name) versus Tag.all.pluck(:name) Using `#map` will instantiate a `Tag` object and do all the slow(er) metaprogramming to get you the syntactic sugar that makes interacting with an ActiveRecord object a treat. It does this, and then you only hit `#name`, completely wasting all that effort. `#pluck` will change the SQL from `select * from tags` to `select tags.name from tags` and never instantiate a `Tag` object, instead short-circuiting and directly fetching the resulting SQL rows — which comes back as an array. It's something along the lines of: ActiveRecord::Base.connection.exec_query(Tag.select(:id).to_sql) Another one I see: ProgrammingLanguage.where(tag_id: @user.tags.select(&:language_tag?).map(&:id)) versus ProgrammingLanguage.where(tag_id: @user.tags.select(:id).where(type: 'LanguageTag')) The first example loops over the loaded `@user.tags`, loads them if they're not already `#loaded?`, selects ones that are `type == 'LanguageTag'`, only to grab the `#id`. The second example joins the two resulting SQL statements and calls `#to_sql` on the second statement, building one query from two queries. Are these times when the first example would be preferred? Yeah, plenty! If your result is already `#loaded?`, then you probably don't need to hit the database again. But for this example and the ones I'm stumbling across while getting our company up-to-speed on "good ways", these are the the commonalities. Save for only very recently, the company I work for hasn't put emphasis on real-world Ruby/Rails skills, instead "if you can code at a high level for any language, we think you can make reasonable contributions to our codebase." This has lead to hiring skilled developers that just don't know that there's a more preferred way of doing things in Rails for different contexts. Double-edged sword, really.
- ohgodplsno 6y agoThat's a consequence of using ORMs. ORMs are a horrible performance mess. Just straight up write SQL. I'm sure Ruby has enough metaprogramming magic to not have to deal with cursors manually.
- 6y ago