Enabling YJIT via Template Doesn't Work

Hi there,

I run a self hosted Discourse install (2026.5.0-latest). Today I tried to turn YJIT on. I added "templates/enable-ruby-yjit.yml" to containers/app.yml and rebuilt the app.

After the rebuild was done, something interesting happened. Inside the Docker container, I ran env | grep RUBY_YJIT_ENABLE and got RUBY_YJIT_ENABLE=1. So far so good. But then I ran sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION' … I got:

YJIT enabled: false

ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +PRISM [x86_64-linux] 

So YJIT was not enabled, despite adding the enable-ruby-yjit.yml template. Then, when I ran sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "GlobalSetting.yjit_enabled=#{GlobalSetting.yjit_enabled}"' I got GlobalSetting.yjit_enabled= — a nil value!

Anyway, after futzing around with it a bit more, I finally got YJIT enabled by adding the following to containers/app.yml:

env:
  DISCOURSE_YJIT_ENABLED: true

I’m sure there’s a bug somewhere (GlobalSetting.yjit_enabled shouldn’t ever return nil) but setting the env variable worked, and I hope someone Googling for this will find this topic.

Isn’t that a misdiagnose? You are checking the ENV of a brand new spawned ruby proccess instead of the one running the actual web server.

If you inspect the /proc/<pid>/environ of the Pitchfork mold process you will see the YJIT env var there.

root@raspberrypi5:/var/discourse# cat /proc/3331660/environ | tr '\0' '\n' | grep -i yjit
RUBY_YJIT_ENABLE=1

Looking at the presence of an env var doesn’t tell you anything about whether Ruby is currently running with YJIT enabled. In this particular case, the env var is set but something else was clobbering the variable Rails uses to enable (or disable) YJIT on startup! (Or at least … that’s my suspicion).

There’s no other explanation for why GlobalSetting.yjit_enabled= returns nil, even on a new Rails instance. There’s also no reason why YJIT should be turned off on a new Rails instance.

After adding the DISCOURSE_YJIT_ENABLED env var to my containers/app.yml,

  1. sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts “YJIT enabled: #{RubyVM::YJIT.enabled?}”; puts RUBY_DESCRIPTION’returns YJIT enabled: true
  2. Memory usage on my server finally goes up (a little).
  3. I finally see a real speed up on my forum.

It should be easy to replicate my findings. Just add the template and see.

This is wrong. At the Ruby level, the ENV var is one of the official toggles, see the Ruby official documentation about this here

This is wrong as DISCOURSE_YJIT_ENABLED only feeds GlobalSetting.yjit_enabled → config.yjit in config/application.rb. Rails uses that to enable YJIT if it isn’t already on. It does not disable an already-enabled YJIT. So when the env var is set, DISCOURSE_YJIT_ENABLED has nothing to do.

To further prove my point I wrote a plugin that returns if YJIT is enabled on my web process:

https://discourse-on-a-pi5.falco.dev/ruby-info

You are confused about the Rails level toggle, which is unnecessary as use the Ruby level toggle.

Huh! So you’re saying we can reliably use the env var to detect if YJIT is enabled! I didn’t know that; thank you for the link to the Ruby documentation.

I’m a little confused about something though. How is it possible that env | grep RUBY_YJIT_ENABLE returns RUBY_YJIT_ENABLE=1, but a new Rails instance in the same container when asked to print #{RubyVM::YJIT.enabled?} outputs false? Shouldn’t it output true since — as you’ve mentioned, this env var works at the Ruby level?

You’re probably really busy and this shouldn’t matter, so no need to answer. I should be able to figure it out on my own server. Could I have your plugin, by any chance? I want a way to be sure that my Discourse server is running on a Ruby with YJIT enabled.

I’ll mark your response as a solution after I’ve replicated.

Thanks in advance!

I’m sorry, I’ve figured it out.

sudo -u discourse scrubs the env. Using the -E flag brings the normal env along, and in that case sudo -E -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION' returns

YJIT enabled: true
ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]

With just the template added.

I apologise for wasting your time, and have marked your response as the solution. Sorry about this. Thank you for investigating and taking the time to respond.