top | item 37579926

Ruby 3.3's YJIT Runs Shopify's Production Code 15% Faster

175 points| nithinbekal | 2 years ago |railsatscale.com

154 comments

order

sho|2 years ago

  > 1.27 million requests per second
  > 3TB/minute of traffic
"rails doesn't scale"

mabbo|2 years ago

That'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.

rapsey|2 years ago

Ok 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.

CaveTech|2 years ago

These 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.

ChadMoran|2 years ago

Rails scales fine. People use that as an escape hatch when they don't know how to write performant code.

Scarbutt|2 years ago

Are there companies in the last 7 years that have started with rails and have become big like spotify?

ChadMoran|2 years ago

People in this thread don't know the difference between performance and scale.

charcircuit|2 years ago

You 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.

bingemaker|2 years ago

What is the hardware spec here?

wgjordan|2 years ago

15% 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|2 years ago

This 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.

rapsey|2 years ago

Time spent profiling and optimizing inherently inefficient technologies is an undervalued factor when deciding what stack to use.

wheels|2 years ago

Am 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.

winrid|2 years ago

They used this stack because it was productive for them.

They don't need to do any of this. The product is fast enough. They make money. It's purely to fatten the bottom line.

alberth|2 years ago

TruffleRuby

What's the current state of Shopify running TruffleRuby, given the tragic loss of Chris Seaton?

Alifatisk|2 years ago

Is 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.

okeuro49|2 years ago

PHP 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.

DylanSp|2 years ago

I'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|2 years ago

> Overall YJIT is 61.1% faster than interpreted CRuby! > On Railsbench specifically, YJIT is 68.7% faster than CRuby!

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

ksec|2 years ago

That is exactly my question as well. Why would I want YJIT if it is only 15% faster than normal Ruby? Given the memory overhead.

stevebmark|2 years ago

Not 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!).

bkazez|2 years ago

15% faster - and how much faster would Java, Rust, or Python be?

dgb23|2 years ago

That’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.

rurban|2 years ago

Next should be github then, I hope