Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@rtomayko
Created June 18, 2010 19:19
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rtomayko/87d574a19372c6043c5f to your computer and use it in GitHub Desktop.
Save rtomayko/87d574a19372c6043c5f to your computer and use it in GitHub Desktop.
unicorn_github
#!/bin/sh
# Usage: unicorn_github
# Script used to start unicorn in GitHub staging and production environments
# with tuned GC environment. This is called primarily by god.
set -e
# Unicorn GC Philosophy
# =====================
#
# The following GC settings have been tuned for GitHub application web requests.
# Most settings are significantly higher than the example configs published by
# Twitter and 37signals. There's a couple reasons for this. First, the GitHub
# app has a memory footprint that's 3x-4x larger than the standard Rails app
# (roughly 200MB after first request compared to ~40MB-50MB). Second, because
# Unicorn is such an exceptional piece of software, we're able to schedule GC
# to run outside the context of requests so as not to effect response times.
# As such, we try to allocate enough memory to service 5 requests without needing
# GC and then run GC manually immediately after each fifth request has been
# served but before the process starts accepting the next connection. The result
# is higher memory use (~300MB per Unicorn worker process on average) and a
# slight increase in CPU due to forced manual GC, but better response times.
# GC Settings
# -----------
# Total number of object slots to allocate at startup. The basic environment
# requires a little over 1M slots. We allocate another 1M slots to provide
# enough room for 5 requests to run before GC needs to kick in. The hottest
# requests average ~75,000 object allocations, which fits nicely into the
# available slots (375,000 objects every 5 requests). Many uncached requests
# can allocate hundreds of thousands of objects, however, so we provide a lot
# of spare room to try to prevent GC in those cases.
export RUBY_HEAP_MIN_SLOTS=2000000
# This is the number of slots that should be available after a GC run. The
# higher this number, the longer GC runs for. If the configured number of
# objects cannot be freed, new slots will be allocated. We set this to the
# same 1M slots as we have spare at startup so the number of slots available
# after the five request out-of-band GC is reset to the same base number. We
# want enough objects to make it another five requests before GC needs to
# kick in again.
export RUBY_HEAP_FREE_MIN=1000000
# If RUBY_HEAP_FREE_MIN slots cannot be freed on a GC run, this number of new
# slots will be allocated. We keep this small because we should hit it only
# rarely and we don't want our object slots to explode when we do.
export RUBY_HEAP_SLOTS_INCREMENT=100000
# Always grow by RUBY_HEAP_SLOTS_INCREMENT exactly.
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
# GC is automatically triggered when this number of calls is made to
# ruby_xmalloc. We really don't want this kicking in so we set it really high.
# I'm not actually sure why it needs to be set to such a large number.
export RUBY_GC_MALLOC_LIMIT=120000000
# Unicorn Boot
# ------------
: ${RAILS_ROOT:=$(dirname $(dirname $0))}
: ${RAILS_ENV:=production}
export RAILS_ROOT RAILS_ENV
cd $RAILS_ROOT
if test "$RAILS_ENV" = "development"
then exec unicorn_rails -c "$RAILS_ROOT/config/unicorn.rb" -E "$RAILS_ENV"
else exec /usr/local/bin/unicorn_rails -c "$RAILS_ROOT/config/unicorn.rb" -E "$RAILS_ENV" -D
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment