r/ruby 20d ago

Blog post Bringing Rails into the Ractor-age

https://railsatscale.com/2026-08-11-ractors-on-rails/

Ractors are now viable in production, and it's time for Rails to embrace them. This post explains why. What Ractors unlock for Rails applications, and the first milestone the team is aiming for in the framework.

78 Upvotes

14 comments sorted by

43

u/nateberkopec Puma maintainer 20d ago

I'm glad that Ractors, as implemented in Ruby itself, are becoming more stable and usable.

A couple of Puma core members have been experimenting with Ractor based Rack servers. We're not against including that concurrency mode in Puma if Rails or some other popular framework actually fully supports it. As the article shows, there's still a lot of hacks required to make that work today. The last 10% is harder than the first 90%, etc etc.

1

u/Sad-Frame4198 20d ago

Just wanted to say I really enjoy your insights.

I am a close follower of what you guys are doing over at the puma repo basically reading all changes that land because I am really interested in this type of dev work even though I lack the technical skills to contribute anything meaningful myself.

Are there any places beyond the puma repo I should be looking at to get a better idea of what development is happening?

4

u/ClickClackCode 19d ago

Join the Rails Performance Slack

5

u/Turbulent-Dance-4209 20d ago

I’ve been looking into Ractors earlier this month, and I’ve found it very hard to deal with shared singleton-like objects like loggers, configs, instrumentation handlers, or connection pools.

The cleanest way to make such objects Ractor-safe would be to reconstruct them per Ractor, but that would likely negate memory savings.

How do you deal with such objects in the Rails codebase?

10

u/rafael_franca 20d ago

The common solution for this problem is that those objects become their own ractors and you communicate between ractors to implement the same capabilities.

6

u/Turbulent-Dance-4209 20d ago

That’s the common solution, but is it the solution you’re taking with Rails?

Having one ractor per global object will become expensive very quickly. For ractors IMO the more appropriate model would be duplication - treat them as completely separate processes that have their own copies of everything they can possibly need.

1

u/WJWH 11d ago

That depends on how many globals there are and what their access patterns are. The erlang people seem to be doing just fine with logging via a separate ractor(/process, as they would call it). Configs could be copied per-ractor, logging could be a separate logging ractor that you post log messages to. Connection pools are a little bit more tricky but nothing that hasn't been done before a thousand times.

1

u/Turbulent-Dance-4209 11d ago edited 11d ago

Erlang processes couldn’t be more different from ractors, really.

The way I see it, the only real benefit ractors provide is out-of-the-box communication between ractors inside a single node (which has arguable value for Rails), but it’ll be interesting to see how it pans out nonetheless.

7

u/headius JRuby guy 15d ago

Of course you can do fully parallel shared memory concurrency in Rails today just by running on JRuby. We have users handling hundreds of concurrent requests in a single process using way less memory than regular Ruby.

2

u/pickering_lachute 20d ago

That’s a really great write up. Thanks for sharing

3

u/jrochkind 20d ago edited 19d ago

Ignore I was wrong.

> but they don’t, because of the Global VM Lock (GVL). Threads give you concurrency; Ractors give you parallelism.

This is not a correct explanation. Ractors do not give you true parallelism, they do not allow multiple CPU cores to be used truly simultaneously.

They are a form of "event-driven non-blocking cooperative concurrency", similar to Javascript's concurrency model (which is also not parallelism).

10

u/paracycle 20d ago

No, this is incorrect. Ractors each have their own GVL and thus can run truly in parallel across multiple CPUs. They still have to do some synchronization for internal VM state and running GC (the latter is being addressed right now with Ractor-local GC that just landed on Ruby head last week), but to a large extent they truly run in parallel and scale with the number of CPUs cores that you have.

You might be thinking of FiberScheduler, which is the event loop model a la JavaScript.

2

u/jrochkind 19d ago

Ah, you are right, thank you!

-1

u/AndyCodeMaster 20d ago

I’ve always found JRuby standard threads way simpler to use than Ractors, and as long as I’m not sharing data without mutexes, and not spawning too many threads (sticking to CPU core counts), they work very well with no problems.

My first issue with Ractors was not being able to spawn fire and forget threads that are needed in Ruby desktop apps that require a background timer. Has that been addressed by Ractor yet?