As we already know (almost?) that we should use background jobs to process long tasks (or even not so long task but can be processed later) to improve performance and user experience, a very common example is sending email.
We often use some gems like: Delayed Job, Sidekiq, Resque... So far so good with many features, such as: retrying, multiple queues, priority... but all of them have to use additional processes which lead to unusable on Heroku with only a free single dyno. In some cases, we just want to have a simple background job and want to run on a free heroku, these gems cannot be used.

Solution

Use Sucker Punch to run background job with single process (the process that is used for running web app).

Usage

  • Add gem 'sucker_punch', '~> 1.0' to your Gemfile, run bundle
  • Create a class (often ends with Job, example: EmailJob) which need to:
    • Include SuckerPunch::Job
    • Define instance method called perform
    • Should be in app/jobs directory (not required but should be)

Example:

#app/jobs/welcome_email_job.rb

class WelcomeEmailJob
  include SuckerPunch::Job

  def perform(user)
    UserMailer.welcome(user).deliver
  end
end
  • Run it: WelcomeEmailJob.new.async.perform(@user)
  • See the awesome thing

Conclusion

  • Use it when you need a simple solution for background jobs in a single process environment like heroku free dyno
  • Don'use it when you need advanced background jobs like: retrying, multiple queues, priority... or you need a high performance background jobs and keep the app run fast
  • Use ActiveJob if you are using rails 4.2+ to make it easily to switch the background job gem. Example: you can use Sucker Punch for staging environment (which run on heroku free dyno) and Delayed Job on production environment.