Autoscale Delayed Job Workers on Heroku Cedar

23 July 2011

Heroku provides an excellent platform to scale your Ruby or Node.js application through the cloud. Built on top of Amazon EC2, Heroku alleviates much of the server administration work typically associated with scaling applications out as user demand increases. Heroku is PaaS; Salesforce and Matz agree.

On the new Cedar stack, scaling your app’s web and background processes across N machines can be achieved using the scale command. While explicit scale commands work well for web processes as traffic increases, background workers tend to have a lot of free time if not managed automatically, running $36 a month per worker.

Several libraries currently autoscale background workers. For Resque based workers, Daniel Huckstep provides a cool approach to scale based on load. For Delayed Job, Heroku’s Pedro Belo has provided a DJ fork which supports autoscaling on Bamboo and Aspen. Additional DJ autoscale libraries include HireFire and Workless.

While I would prefer to use Github's Resque for performance and manageability, to avoid an additional, potentially paid dependency on Redis at this stage, I am currently using Pedro's Delayed Job autoscaling fork with a few changes to support Cedar.

This implementation will autoscale a single worker up and down as background requests are generated by the application. Job retries are not currently supported. To use, create an initializer similar to below. In your local development environment, the rush library provides process management.

Delayed::Worker.auto_scale = true
Delayed::Worker.max_attempts = 1

if Rails.env.production?
    Delayed::Worker.auto_scale_manager = :cedar
else
    Delayed::Worker.auto_scale_manager = :local
end

To schedule a custom background job or delay send from a mailer, respectively:

Delayed::Job.enqueue YourAwesomeJob.new
UserMailer.delay.welcome_email(context)

In your Procfile, add:

worker: bundle exec rake jobs:work

Efficiently autoscaling your background workers eliminates spending for idle dynos. For a background load of 20 hours per month, you’d pay $1 autoscaling compared to $36 for an idle background worker running the entire month.

By Aaron Dunnington

Related Articles