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)

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.