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.