Picture of the author

GAURAV VARMA

← BACK TO BLOG

Rails 7 adds load_async to ActiveRecord for parallel queries


Rails 7 adds load_async, a new ActiveRecord method that schedules SQL queries to run on a background thread pool. This allows independent queries to be executed in parallel—saving time, reducing I/O wait, and improving controller performance.

Why it matters

In many Rails controllers, we often load multiple unrelated datasets:

1@car_types = CarType.all
2@cars = Car.order(released_at: :desc)

These queries are executed sequentially, which means we spend time waiting on each I/O operation one after another. If each query takes 50ms, that’s 100ms total. But if performed in parallel, we could reduce that to 50ms.

Before Rails 7

A naive attempt might involve spinning up a raw thread:

1car_types_future = Thread.new { CarType.all.to_a }
2@cars = Car.order(released_at: :desc).to_a
3@car_types = car_types_future.value

But this introduces all sorts of thread-safety concerns, especially around CurrentAttributes, ActiveSupport instrumentation, and request-local state. It's brittle and hard to manage.

The Rails 7 approach

Now with load_async, you can do:

1@car_types = CarType.all.load_async
2@cars = Car.order(released_at: :desc).load_async

Each query runs in a background thread from a dedicated pool. When you access the result later, Rails ensures the query has completed—either in the background or, if necessary, in the foreground.

The actual instantiation of models still happens on the main thread, so there's no risk of thread-safety issues with Rails internals.

Summary

load_async makes it effortless to overlap I/O for unrelated database queries in your controllers. It’s a simple yet powerful way to improve responsiveness in Rails apps—no thread hacks, no extra gems, just built-in Rails magic. Check out this Pull Request for more details.