Saturday, February 9, 2013

Heroku: Scaling Dynos at night and in the morning

I needed a rake task to auto scale Dynos on Heroku; wind them down at night and wind them up in the morning. I found this helpful post on Stackoverflow. I made a few modifications and would up with this:

namespace :scale_dynos do
  require 'heroku-api'
  desc "scales up dynos"
  task :up do
    dyno_max = [6,0].include?(Time.now.wday) ? ENV['WEEKEND_DYNO_MAX'] : ENV['DYNO_MAX']
    heroku = Heroku::API.new(:api_key => ENV['HEROKU_API_KEY'])
    heroku.post_ps_scale(ENV['APP_NAME'], 'web', dyno_max.to_i)
  end

  desc "scales down dynos"
  task :down do
    dyno_min = ENV['DYNO_MIN']
    heroku = Heroku::API.new(:api_key =>  ENV['HEROKU_API_KEY'])
    heroku.post_ps_scale(ENV['APP_NAME'], 'web', dyno_min.to_i)
  end
end


It adjusts for the weekend to scale to a different level if you set the ENV varaible. Additionally here is how I set the Heroku config vars. The add command does them all at once but the remove goes through one by one, removes the VAR and restarts the app.

heroku config:add DYNO_MIN=1 DYNO_MAX=25 WEEKEND_DYNO_MAX=1 APP_NAME=<your app name> HEROKU_API_KEY=<your api key> -a <your app name>
heroku config:remove DYNO_MIN DYNO_MAX WEEKEND_DYNO_MAX APP_NAME HEROKU_API_KEY -a <your app name>

You will need the heroku-api gem. I also set the Gemfile entry to this:

gem 'heroku-api', :require => false

Since the rake task is called twice a day there was no need to load the gem into memory for the rest of the time.

2 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Thank you for the post, it helped me find a way through this!
    While we are at it, I'd like to mention that to call the script you should run something like "rake namespace:task" !

    ReplyDelete