Thursday, February 14, 2013

Heroku with Unicorn backlog settings and performance

In light of this post from Rap Genius and subsequent blow up on Hacker News I decided to share what we did to play with the request queue on Unicorn & Heroku.

In the app/config/unicorn.rb we changed the backlog line to this:

:backlog => Integer(ENV['UNICORN_BACKLOG'] || 200)

And then we can alter the backlog as necessary via:

heroku config:set UNICORN_BACKLOG=25 -a <app_name>

We found 25 to be a sweet spot for two Unicorn Workers but it may be different with four (which we are experimenting with now). Again this is also relative to the app so your results may (and probably will) be different.

Update:

I neglected to mention that you have to move the port declaration from config.ru and put it in the unicorn.rb too. The full line should be something like this:

listen ENV['PORT'], :backlog => Integer(ENV['UNICORN_BACKLOG'] || 200)

Saturday, February 9, 2013

Formatting Source for a blog post

I found this handy blog post for formatting my source code to place here in my last blog post. I encourage you to check it out!

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.