33 ms·
Ruby 3.3's YJIT Runs Shopify's Production Code 15% Faster
- sho 3y ago> 1.27 million requests per second > 3TB/minute of traffic "rails doesn't scale"
- ChadMoran 3y agoRails scales fine. People use that as an escape hatch when they don't know how to write performant code.
- Gigachad 3y agoYou don't even have to write performant code. You can just start as many instances of the rails app as you want. The bottleneck is usually the database.
- bingemaker 3y agoWhat is the hardware spec here?
- charcircuit 3y agoYou need the number of servers and server specs to answer that question. Even if a piece of software could only handle 1 request per second you could handle 1.27M requests if you just run 1.27M servers.
- CaveTech 3y agoThese two points are entirely unrelated. Scaleability in that meme is not considering horizontal scalability, which approaches infinity for literally any language/framework. It only makes sense in the context of vertical scalability, and gross req/sec offers no insight into whether or not that's true.
- Gigachad 3y agoI can't see how vertical scalability even matters for rails You can just start more instances. It's not like two active web requests need to interact with each other.
- deleted 3y ago[deleted]
- mabbo 3y agoThat's not on a per-host basis. Shopify's design is, quite fortunately, one that partitions really well, as each store is completely independent of each other. Each store can be assigned to one pod, each pod can have as many hosts as it takes to optimize the use of a database instance, and then you can add more pods as the need arises. Edit: to be clear, that's not to say Rails can't scale. It can. It's just that it doesn't need to- you can scale anything with enough partitioning.
- choilive 3y agoSure.. but isn't that a database problem and not a rails problem?
- mabbo 3y agoNo, they both matter. The database can handle X shops per partition, and the rails host can handle Y shops per partition. If rails were half as fast, you'd need twice as many rails hosts (but no more databases).
- phamilton 3y ago> but no more databases Sort of. Twice as many rails hosts means more DB connections which generally means more load/memory on the DB or more load/memory on the external connection pooler. It's only a bit of incremental load, but it's easy to overlook how many other systems need to run to make Rails scale.
- brianwawok 3y agoNo he’s his examples he’s talking 50 stores over 10 machines vs 50 stores over 5 machines. Both would require the same DB count, but the second would save on server costs for stores.
- mabbo 3y agoI think the above means (if I do get the point) that databases scale in terms of both requests per second and number of active connections. Having 1000 connections doing 1 request per second isn't the same as having 1 connection doing 1000 requests per second. But, and I could be wrong, the larger factor is the number of requests per second.
- Scarbutt 3y agoAre there companies in the last 7 years that have started with rails and have become big like spotify?
- rognjen 3y ago(I assume you mean Shopify not Spotify) No exactly a fair question because Shopify is much older and is valued at 70B. For a company to have done it in half the time would have been impressive regardless of tech whereas on average it takes 7 years to become a unicorn. I do know that Aircall is relatively young, on a good trajectory and runs Rails.
- rahoulb 3y agoDepends on your definition of big. Partly, you need mobile now, so any Rails stuff is likely to be back-end and hidden. Plus big investors like to go for the exciting stuff. But if you're looking at companies aren't household names (taking smaller amounts of investment), there are lots out there. Syft (recruitment) were founded in 2016 and have revenues of over $100m per year - although that's partly due to acquisition by a larger competitor, so when I just looked, separating their valuation from the group wasn't immediately obvious. I've freelanced and contracted across a few niche industries (construction, print, airport signage management!) where I was building something against competitor software that I discovered was at least partially built with Rails. Those big players in each niche would have revenue in the tens of millions and from what I could see, very small technical teams. But anyone outside those industries would never have heard of these companies.
- rapsey 3y agoOk now what is the cost of all the instances. And how many instances would be required if Go/Rust would have been used? Also what is the cost in man hours spent on optimizations and profiling.
- berkle4455 3y ago> And how many instances would be required if Go/Rust would have been used? Zero. Because Shopify would have waited until Rust came out in 2015, instead of launching in 2006, and they would never have gotten off the ground and been another failed techbro startup that instead of getting shit done, bikeshedded over languages. PHP and Ruby apps have generated far more revenues than all the Rust and Golang code combined.
- pjmlp 3y agoOr they could have used something available in 2006, like C++, Java, .NET/C#, OCaml, Haskell, D.
- moonchrome 3y agoC# in 2006 was a joke, probably worse than Rails in performance. This was the webforms era and old EF - meant for enterprise customers with a couple of hundred active users max... ASP.NET being a competitive/performant framework is a very recent development (since core basically which became usable past 2.0) Haskell, OCaml and D are niche languages, probably aren't mature enough now to use for a production system that needs to scale (in terms of org growth and building complex systems). Java web frameworks were also terrible in 2006 (this is the Java era that gave Java it's reputation) and the only thing worse for productivity I can think of is C++ hahaha ...
- pjmlp 3y agoA joke is this comment. All of them were faster and used less resources than a very slow interpreted language, by having JIT and AOT compilers, state of the art GC and great IDE offerings, even the niche ones had better tooling (Leksah and Merlin, versus nothing).
- hnisforfascists 3y ago[dead]
- ChadMoran 3y agoPeople in this thread don't know the difference between performance and scale.
- wgjordan 3y ago15% faster is great. But at what cost? > Since Ruby 3.3.0-preview2 YJIT generates more code than Ruby 3.2.2 YJIT, this can result in YJIT having a higher memory overlead. We put a lot of effort into making metadata more space-efficient, but it still uses more memory than Ruby 3.2.2 YJIT. I'm hoping/assuming the increased memory usage is trivial compared to the cpu-efficiency gains, but it would be nice to see some memory-overhead numbers as part of this analysis.
- nomilk 3y agoThis is a particularly valid concern given ruby+rails seems quite memory inefficient to begin with. I've sometimes had smallish apps on 500mb heroku dynos crashing due to memory slowly climbing and eventually slowing things down as the dyno uses swap, and eventually 500mb of swap. IME ruby+rails doesn't seem to free up memory after it uses it, and that causes problems as the hours go by until the pod/dyno crashes or is restarted.
- Ocha 3y agoI’ve observed same, and every time I switched to jemalloc and the issue was fixed.
- nomilk 3y agoWas it difficult to switch? What were the downsides / tradeoffs? (I read about jemalloc recently but don't know enough about it to confidently pursue it, but may try it on a small app if it's straight forward).
- Ocha 3y agoSuper easy and have not had an issue with it in over 10 years of using it. There is an example here on how to do it with docker image. https://mailsnag.com/blog/optimized-ruby-dockerfile/ https://mailsnag.com/blog/optimized-ruby-dockerfile/.
- 3y ago
- alberth 3y agoTruffleRuby What's the current state of Shopify running TruffleRuby, given the tragic loss of Chris Seaton?
- Alifatisk 3y agoIs TruffleRuby compitable with Rails? If so, I wonder how much TruffleRuby would improve the performance and memory footprint. Especially with native images, I wonder how that would turn out.
- byroot 3y ago> Is TruffleRuby compitable with Rails? Rails proper, yes. Small rails app are generally drop-in compatible, but sizeable applications are likely to run in a few compatibility issues as most gems aren't tested against TruffleRuby. > I wonder how much TruffleRuby would improve the performance and memory footprint. The generally speaking Truffle is much faster at "peak" performance, but take very long to get there which makes it challenging to deploy. It also uses way more memory, but it's partially offset by the fact that it doesn't have a GVL, so you get parallel execution with threads.
- Alifatisk 3y agoThank you for the informative reply. Ruby atm is working towards implementing true parallell execution with Ractors for example, and now with YJIT, the performance might increase some more.
- ufuk 3y agohttps://railsatscale.com/2023-06-12-truffleruby-in-shopify-ci/ https://railsatscale.com/2023-06-12-truffleruby-in-shopify-c...
- rapsey 3y agoTime spent profiling and optimizing inherently inefficient technologies is an undervalued factor when deciding what stack to use.
- wheels 3y agoAm I really going to have to get out the premature optimization quote? Most businesses fail. Those that don't fail, usually don't have interesting scaling issues. (You can go a really long way on a boring monolith stack.) So in most cases, whatever gets things out into the world and able to see if the business can be validated makes sense, and then you optimize later. A nonscalable stack that you can iterate on 50% faster is more likely to produce a viable company than a more scalable stack that's slower to work with. If you're a hired employee, it's easy to forget that the place you're working for is already a big exception just by the virtue of it grew large enough to hire you.
- berkes 3y agoThis hints at a false dichotomy. One that especially Ruby and Rails keep afloat. Productivity and Scalability(in performance sense) aren't opposites. Take Bash. Performs bad and is a guarantee for terrible productivity in a large category of software. But perfect for a niche. Take Java. Performs better than many, and allows for good productivity (if you avoid the enterprise architectures, but that goes for any language). Or take Rust. Productivity much higher than most C/C++ and in my case higher than with Ruby/Rails, and also much more performant.
- fiedzia 3y ago> Productivity and Scalability(in performance sense) aren't opposites. They often clash with each other. Rust for example is a lot less pleasant to debug than interpreted languages and that is a loss of productivity.
- berkes 3y agoNot in my case. Rust, for me, is much better for productivity than my other major languages Ruby and JavaScript. The main reason is type enforcement, which is why -for me- typescript is much more productive than JavaScript. A large category of bugs simply won't exist (are caught at compiletime). With Ruby, I'd have to write hundreds of edge-case unit-tests just to cover stuff that, with Rust is enforced compile-time for me. The other reason is runtime speed. A typical Ruby test-suite takes me minutes to run. A typical Rails test suite tens of minutes. A typical Rust test-suite takes < a minute to compile and seconds to run. I run my tests hundreds of times per day. With a typical Rails project, I'm waiting for tests upwards of an hour per day (yes, I know guard, fancy runners with pattern matching etc). The last reason, for me, is editor/IDE integration: Rust (and TS) type system make discovery, autocomplete and even co-pilot so much more useful that my productivity tanks the moment I'm "forced" to use my IDE with only solargraph to help. And debugging: sure! I've had reasonable success with gdb and ruby debuggers in the past. Rust's gdb isn't much better. But stepping through a stack in a rails project is a nightmare: the stack is often so ridiculous deep (but it does show how elegant and neat it's all composed!) that it's all noise and no signal. Leaving a binding.pry or even `throw "why don't we get here?!"` also works, but to call that "productive" debugging is a stretch, IMO.
- stevebmark 3y agoNot to be pessimistic, but does this matter? Rails apps take 2-3x more resources to run than most other language stacks, including other dynamic languages, (including Perl!).
- rurban 3y agoNext should be github then, I hope
- bkazez 3y ago15% faster - and how much faster would Java, Rust, or Python be?
- dgb23 3y agoThat’s not easy to answer, because it’s not quite an apples to apples comparison if you start factoring in libraries, frameworks and the specific workload. My rule of thumbs: Python has similar performance characteristics as Ruby. With Java/C#/Go you’d expect about an order of magnitude of improvement. With naive Rust/C++ you would likely be at the same average speed as Java for web applications but with less memory usage. Well until you make an effort to produce faster code.
- turbo_fart 3y agoNode.js is about 20x faster than RoR for instance
- andreime 3y agoAt what? At running calculations? How do you compare a runtime with a framework? I'm genuinely curious...
- okeuro49 3y agoPHP went through some crazy performance improvements from PHP 5.6 to 7.0, in some cases running twice as fast. It's good to see Ruby doing the same. There is something neat about the same code running faster, solely by being on an upgraded platform.
- hu3 3y agoYep. And PHP is possibly getting an optimizing compiler: https://www.reddit.com/r/PHP/comments/16hu7dq/php_is_getting_a_real_optimizing_compiler/ https://www.reddit.com/r/PHP/comments/16hu7dq/php_is_getting...
- DylanSp 3y agoI'm probably misinterpreting the numbers, but it sounds like the 3.3 interpreter also got some significant performance improvements - if 3.3 YJIT got a 13% speedup compared to 3.2 YJIT and a 15% speedup compared to 3.3 interpreter, that sounds like the 3.2 YJIT has only slightly better performance than the 3.3 interpreter. Is that interpretation correct? If so, what were the improvements in the 3.3 interpreter, or was 3.2 YJIT just not much of a speedup?
- p8 3y ago> Overall YJIT is 61.1% faster than interpreted CRuby! > On Railsbench specifically, YJIT is 68.7% faster than CRuby! https://speed.yjit.org/ https://speed.yjit.org/ For 3.2 there also was an improvement of the interpreter: > We now speed up railsbench by about 38% over the interpreter, but this is on top of the Ruby 3.2 interpreter, which is already faster than the interpreter from Ruby 3.1. According to the numbers gathered by Takashi, the cumulative improvement makes YJIT 57% faster than the Ruby 3.1.3 interpreter. https://shopify.engineering/ruby-yjit-is-production-ready https://shopify.engineering/ruby-yjit-is-production-ready
- ksec 3y agoThat is exactly my question as well. Why would I want YJIT if it is only 15% faster than normal Ruby? Given the memory overhead.
- p8 3y agoThe 15% is for the total request time including waiting for blocked IO. > All that work allowed us to speedup our storefront total web request time by 10% on average, which is including all the time the web server is blocked on IO, for example, waiting for data from the DB, which YJIT obviously can't make any faster. https://twitter.com/paracycle/status/1605706245955997697 https://twitter.com/paracycle/status/1605706245955997697