Save $414 on Your Heroku Bill This Year

Run Delayed Job in threads to eliminate dedicated dynos for background jobs on Heroku.

2019 UPDATE: Since I wrote this post, there are more preferable options to the guidance provided here. Specifically, to alleviate the need for worker dynos on Heroku with Rails 5+, you can utilize the async adapter or if you want a little more configurability utilize SuckerPunch. Both utilize background threads (and pools) to execute jobs. Neither provide support for durable jobs or retries, but there many other options if you have those requirements. Your applications may benefit from having support both for ‘instant’ thread-based jobs and ActiveJob backed by a persistent queue for more mission critical tasks.

Many of the Rails projects I’ve worked on consist of sophisticated web front-ends with a simple asynchronous background processing to send emails, improve interface responsiveness, run scheduled tasks, and maintain up-to-date data sources. I’ve had great success with Delayed Job in particular.

On Heroku, the traditional guidance is that Delayed Job should run on a dedicated ‘worker’ dyno for $34.50 a month. Since the first web dyno is free, wouldn’t it be great to be able to avoid worker dynos altogether for smaller apps and run background jobs in a thread on the web dynos? The general approach should work for any stack, here’s how to do it for Delayed Job + Active Record in your Rails app.

  1. Upgrade to the threaded Puma Webserver
  2. Add this snippet of code to your delayed_job.rb initializer
  3. Restart your app.
  4. Profit.