Rails at Scale
railsatscale.com · Company blog · on HN since 2023
Shopify engineers write about Ruby and Rails performance, including YJIT, parser work, and Ruby tooling.
What HN saysCommenters cite it for YJIT's speed gains and the post on Ruby outperforming C, with one clarifying that it compared pure Ruby to a C extension.
59HN people shared it
28linked it in comments
77stories submitted
2.0Kstory points
2 months agolast shared
2023people per year2026
Most-shared posts
- 1Ruby Outperforms C: Breaking the Catch-2214 people · 9 points · first shared 2023 · discussion on HN
- 2Interprocedural Sparse Conditional Type Propagation5 people · 79 points · first shared 2025 · 11 comments on HN
- 3Performance impact of the memoization idiom on modern Ruby5 people · 5 points · first shared 2023 · discussion on HN
- 4Ruby 3.3's YJIT: Faster While Using Less Memory4 people · 28 points · first shared 2023 · discussion on HN
- 5YJIT 3.4: Even Faster and More Memory-Efficient4 people · 23 points · first shared 2025 · 2 comments on HN
- 6Rewriting the Ruby Parser4 people · 4 points · first shared 2023 · discussion on HN
- 7Ruby 3.3's YJIT Runs Shopify's Production Code 15% Faster4 people · 4 points · first shared 2023 · discussion on HN
- 8One engine, many tools – Introducing Rubydex4 people · 4 points · first shared 2026 · discussion on HN
- 9Mastering Ruby Code Navigation: Ruby LSP Enhancements in the First Half of 20243 people · 143 points · first shared 2024 · 67 comments on HN
- 10Rewriting the Ruby Parser3 people · 51 points · first shared 2023 · 10 comments on HN
- 11ZJIT has been merged into Ruby3 people · 50 points · first shared 2025 · 6 comments on HN
- 12Two Garbage Collection Improvements Made Our Storefronts 8% Faster3 people · 7 points · first shared 2023 · discussion on HN
- 13Faster Ruby Bundler3 people · 3 points · first shared 2026 · discussion on HN
- 14Tiny JITs for a Faster FFI2 people · 316 points · first shared 2025 · 138 comments on HN
- 15Fast Allocations in Ruby 3.52 people · 279 points · first shared 2025 · 67 comments on HN
What HN people wrote when they linked it
Lio · 2025-11-18
I was actually hoping it would be four JITs and we'd get Tenderlove's tiny FFI JIT too.
https://railsatscale.com/2025-02-12-tiny-jits-for-a-faster-ffi/
aw1621107 · 2025-11-09
> actually, in some cases, it outperforms C -> https://railsatscale.com/2023-08-29-ruby-outperforms-c/
Bit of a clarification after reading the article - that article demonstrates a pure-Ruby implementation [0] outperforming a C extension [1], which is not what I had originally expected when first clicking on the link.
[0]: https://github.com/tenderlove/tinygql
[1]: https://github.com/rmosolgo/graphql-ruby/tree/master/graphql-c_parser
hahahacorn · 2025-02-12
There's a phenomenal breakdown by JPCamara (https://jpcamara.com/2024/12/01/speeding-up-ruby.html) on why the Ruby#each method was rewritten in Ruby (https://bugs.ruby-lang.org/issues/20182). And bonus content from tender love: https://railsatscale.com/2023-08-29-ruby-outperforms-c/.
TL;dr - JIT rules.
ciconia · 2023-12-25
I believe with version 3.3 Ruby is back in a big way! The language focused on developer happiness and derided for its slowness is slow no more.
YJIT is an amazing technology, and together with other innovations like object shapes and various GC optimizations, Ruby is becoming seriously fast! Big Ruby shops such as Shopify [1] have been running 3.3 pre-release with YJIT and reporting double digit percentage performance improvements.
Personally I'm really excited about Ruby and its future. I can't wait to start working with Ruby 3.3 and using it on my client's production sites...
[1] https://railsatscale.com/2023-09-18-ruby-3-3-s-yjit-runs-shopify-s-pro…
Edit: add percentage to performance improvements.
lloeki · 2026-02-14
Isn't LuaJIT kind of a dead end?
Also Ruby has been getting quite fast since YJIT (and now ZJIT):
https://railsatscale.com/2023-08-29-ruby-outperforms-c/
tekknolagi · 2025-12-27
Yes; see the first ZJIT blog post. https://railsatscale.com/2025-05-14-merge-zjit/
riffraff · 2025-12-26
ZJIT exists because it's a more traditional design and there's hope more people will have a easier time contributing[0]. Given that, it seems YJIT will become unnecessary if ZJIT succeeds.
0: https://railsatscale.com/2025-05-14-merge-zjit/
byroot · 2025-12-25
I know that tweet, it's real, but that doesn't contradict my comment.
They indeed replaced Unicorn by Falcon in one application, but falcon is configured in "Unicorn mode" (no concurrent requests). So the gain is effectively 0.
Also note how they don't share any performance metrics, contrary to https://railsatscale.com/2023-10-23-pitchfork-impact-on-shopify-monoli…
wutwutwat · 2025-11-08
> if you ignore performance
man, people are still parroting decade old, incorrect talking points I see.
Is ruby as performant as C, probably not, although, actually, in some cases, it outperforms C -> https://railsatscale.com/2023-08-29-ruby-outperforms-c/
One of the largest ecommerce apps in the world runs ruby, shopify. Ruby now has a JIT, there has been insane effort put into making ruby faster.
Someone · 2025-08-20
tinnet · 2025-07-05
this sounds so different from rubys new JIT that - i think - came in around the same time and is bringing huge performance benefits.
team size sounds similar but it's mostly full time people from shopify and other interested parties (see https://railsatscale.com/2025-01-10-yjit-3-4-even-faster-and-more-memo… and similar)
molf · 2025-05-22
C itself is fast; it's calls to C from Ruby that are slow. [1]
Crossing the Ruby -> C boundary means that a JIT compiler cannot optimize the code as much; because it cannot alter or inline the C code methods. Counterintuitively this means that rewriting (certain?) built-in methods in Ruby leads to performance gains when using YJIT. [2]
[1]: https://railsatscale.com/2023-08-29-ruby-outperforms-c/ [2]: https://jpcamara.com/2024/12/01/speeding-up-ruby.html
alberth · 2025-05-22
Can someone explain, is YJIT being abandoned over the new ZJIT? [0]
And if so, will these YJIT features likes Fast Allocations be brought to ZJIT?
https://railsatscale.com/2025-05-14-merge-zjit/
igouy · 2025-02-15
Maybe "Ruby Outperforms C" was bait for "Outperforming a C extension" which is about the relative cost of calling C from Ruby?
https://railsatscale.com/2023-08-29-ruby-outperforms-c/
jez · 2024-12-23
For those curious, this article is a good introduction to the topic:
https://railsatscale.com/2023-10-24-memoization-pattern-and-object-sha…
ckolkey · 2024-09-09
Oh, that meme is old, sorry to say. Here's a nice blog post about ruby outperforming C with the new JIT compiler. Fun times :)
https://railsatscale.com/2023-08-29-ruby-outperforms-c/
haven · 2024-08-02
Dynamically typed languages aren't out in the cold like they used to be with IDE support. Most of the advanced LSP work going on isn't based on explicit types signatures yet they work well. See https://railsatscale.com/2024-07-18-mastering-ruby-code-navigation-maj…
thomascountz · 2024-07-13
Excitingly, Ruby 3.3+ shipped with a new alternative parser called Prism[0]! See also: [1][2].
[0]: https://github.com/ruby/prism
[1]: https://railsatscale.com/2023-06-12-rewriting-the-ruby-parser/
[2]: https://railsatscale.com/2024-04-16-prism-in-2024/
czbond · 2024-02-21
Where would the YJIT 3.3 performance improvements be mostly seen? (eg: task type)
edit: https://railsatscale.com/2023-12-04-ruby-3-3-s-yjit-faster-while-using…
edit 2: YJIT or truffle these days?
mwgalloway · 2023-12-26
Ruby 3.3 has made major improvements to the debugging experience: https://railsatscale.com/2023-12-19-irb-for-ruby-3-3/
pdimitar · 2023-12-26
I haven't seen 80% anywhere in the linked article[0] so let's use facts and not beliefs.
It is possible Ruby itself got accelerated a lot, okay, I am just not sure that's relevant since almost all Ruby usage is Rails.
[0] https://railsatscale.com/2023-09-18-ruby-3-3-s-yjit-runs-shopify-s-pro…
TobiasBales · 2023-12-19
https://railsatscale.com/2023-08-29-ruby-outperforms-c/ by Aaron comes to mind
norman784 · 2023-11-12
I'm not too invested in ruby but AFAIK they built a new parser from scratch, that was portable, that means that all the other projects like rubocop, solargraph (or how the ruby lsp is called) and all other ruby implementations can use it, so it will be easier from now on to maintain those projects up to date with the official ruby parser.
You can read more about the parser I mentioned here (but it seems that is has/hat a different name before?) https://railsatscale.com/2023-06-12-rewriting-the-ruby-parser/
leipert · 2023-11-12
I think it was developed under the name YARP by Shopify: https://railsatscale.com/2023-06-12-rewriting-the-ruby-parser/
HN thread: https://news.ycombinator.com/item?id=36310130
Malp · 2024-12-25
Just-in-time compilation of Ruby allowing you to elide a lot of the overhead of dynamic language features + executing optimized machine code instead of running in the VM / bytecode interpreter.
For example, doing some loop unrolling for a piece of code with a known & small-enough fixed-size iteration. As another example, doing away with some dynamic dispatch / method lookup for a call site, or inlining methods - especially handy given Ruby's first class support for dynamic code generation, execution, redefinition (monkey patching).
From https://railsatscale.com/2023-12-04-ruby-3-3-s-yjit-faster-while-using…
> In particular, YJIT is now able to better handle calls with splats as well as optional parameters, it’s able to compile exception handlers, and it can handle megamorphic call sites and instance variable accesses without falling back to the interpreter.
> We’ve also implemented specialized inlined primitives for certain core method calls such as Integer#!=, String#!=, Kernel#block_given?, Kernel#is_a?, Kernel#instance_of?, Module#===, and more. It also inlines trivial Ruby methods that only return a constant value such as #blank? and specialized #present? from Rails. These can now be used without needing to perform expensive method calls in most cases.
nirvdrum · 2023-06-14
Your phrasing could be misconstrued by those not familiar with the history. Shopify hasn't been developing TruffleRuby for 10 years. The entire TruffleRuby project is 10 years old, including the first 12 - 18 months where it was a humble intern project. TruffleRuby (previously called JRuby+Truffle) was initially a research project for testing out optimizations, not a production-quality implementation suitable for deployment. I think it's now a viable deployment target, but that wasn't true 10 years ago.
As you might imagine, there's a lot more to production deployments than simple Ruby compatibility. At Shopify, we've recently modified our CI system to support TruffleRuby and are actively running projects against TruffleRuby in CI now [1]. The TruffleRuby 23.0.0 release coming out in the next day or so includes quite a few compatibility issues we've worked out getting a large Rails app booting. That project is on the order of months, not decades.
YARP will make adoption of TruffleRuby easier. Absent a language specification, implementations like JRuby and TruffleRuby have to match what CRuby is shipping and that by necessity means they lag after CRuby releases. Parser changes are amongst the hardest things to port over. YARP eliminates most of the challenges there.
[1] -- https://railsatscale.com/2023-06-12-truffleruby-in-shopify-ci/
Disclaimer: I'm on the TruffleRuby team at Shopify.
wg0 · 2023-06-13
I think llvm is not going to be irrlevent rather the amount of new languages that we see mostly depend on llvm IR.
That helps them to reach multiple architectures which is especially even more important since Apple moved away from x86 to ARM.
Writing two backends for two different architectures would be a lot of work and then lots of platform specific optimizations therefore llvm is the present and seems to be the future for the foreseeable future as well.
Besides that, we or at least I studied and was implied that hand written recursive descendant parsers are inferior way of doing things. Real world usage should always start with a grammer handed over to a parser generator (bison etc) that in turn have LR(1) algorithms driven by tables.
Turns out that a of lot of widely used programming languages are moving away from LR(1) and having their parsers as hand written recursively descendent parsers.
Ruby seems to be switching away from generated LR(1) parsers, more details here [0]
EDIT: References.
[0] https://railsatscale.com//2023-06-12-rewriting-the-ruby-parser/