Rails 7.1 adds ActiveJob.perform_all_later

Vishnu M

By Vishnu M

on February 28, 2023

This blog is part of our  Rails 7 series.

Rails 7.1 adds ActiveJob.perform_all_later to enqueue multiple jobs at once. This method accepts an array of job instances. Just like Active Record bulk methods, perform_all_later doesn't run any callbacks.

For example, if we want to send a welcome email to multiple users, we can do this:

1welcome_email_jobs = users.map do |user|
2  WelcomeEmailJob.new(user)
3end
4
5ActiveJob.perform_all_later(welcome_email_jobs)

The benefit of doing it this way rather than looping through the user records and using perform_later is that perform_all_later cuts down on the number of round-trips to the queue datastore. That means reducing Redis round trip latency if the queuing backend is Sidekiq. Whereas if we're using a queuing backend like GoodJob, which is backed by Postgres, perform_all_later will enqueue all the jobs using a single INSERT statement which is more performant.

Please note that if the queuing backend doesn't support bulk enqueuing, perform_all_later will fallback to enqueuing each job individually.

Active Job is designed to abstract away the differences between different job processing libraries and to provide a unified interface. It is made possible using adapters.

The popular queuing backend Sidekiq already has a push_bulk method. Hence, the author of this pull request has made changes to the Sidekiq adapter so that perform_all_later uses the push_bulk method from Sidekiq.

Recently, GoodJob has also added support for bulk enqueuing in this pull request.

Practically, ActiveJob.perform_all_later is only useful if we want to push thousands of jobs at once. For a smaller number of jobs, the performance benefits will not be significant.

Please check out this pull request for more details.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.