Deploying your Rails app to Heroku is generally straight forward, however there's a lot of additional configuration needed to make sure things scalable and memory efficient. The following are some tips and recommendations on setting up your Rails app on Heroku.
Note, before setting these environment variables or adding the buildpacks, make sure you’ve first deployed your Rails app to Heroku. Adding these variables or buildpacks before can mess up the initial setup process.
Jemalloc Buildpack
jemalloc is a general purpose malloc implementation that works to avoid memory fragmentation in multithreaded applications. This buildpack makes it easy to install and use jemalloc on Heroku and compatible platforms.
You can add the jemalloc
buildpack by running the following.
heroku buildpacks:add --index 1 https://github.com/gaffneyc/heroku-buildpack-jemalloc.git
Next you'll need to set the JEMALLOC_ENABLED
environment variable on Heroku.
heroku config:set JEMALLOC_ENABLED=true
More information at elements.heroku.com/buildpacks/gaffneyc/heroku-buildpack-jemalloc.
Postgres Bouncer Buildpack
This is a Heroku buildpack that allows one to run pgbouncer in a dyno alongside application code. The primary use of this buildpack is to allow for transaction pooling of PostgreSQL database connections among multiple workers in a dyno.
Add the heroku-buildpack-pgbouncer
buildpack by running.
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-pgbouncer
Next, either add or update your Procfile
, the below is assuming you are using Sidekiq.
web: bin/start-pgbouncer-stunnel bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq -C config/sidekiq.yml
Important, in your config/database.yml
ensure the following flags are set in your production
environment.
advisory_locks: false
prepared_statements: false
More information at elements.heroku.com/buildpacks/heroku/heroku-buildpack-pgbouncer.
Set Rails Master Key
If you are using config/credentials.yml.enc
, you'll need to set the RAILS_MASTER_KEY
environment variable.
heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
Change Service Timeout
You can specify request timeout by setting the RACK_TIMEOUT_SERVICE_TIMEOUT
environment variable.
heroku config:set RACK_TIMEOUT_SERVICE_TIMEOUT=20
More information at devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#timeout.
Set Sensible Defaults
If a Ruby application has the configuration variable SENSIBLE_DEFAULTS set, then the configuration variable WEB_CONCURRENCY will be defaulted to a value based on the dyno size.
heroku config:set SENSIBLE_DEFAULTS=enabled
More information at devcenter.heroku.com/changelog-items/618.
Enable Preboot
Preboot changes the standard dyno start behavior for web dynos. Instead of stopping the existing set of web dynos before starting the new ones, preboot ensures that the new web dynos are started (and receive traffic) before the existing ones are terminated. This can contribute to zero downtime deployments.
You can enable preboot functionality by running the following.
heroku features:enable preboot
More information at devcenter.heroku.com/articles/preboot.
Enable Runtime Heroku Metrics
To provide additional insights into memory health we offer optional language-specific runtime metrics. JVM, Go (public beta), Node.js (public beta), and Ruby (public beta) are currently supported.
heroku labs:enable "runtime-heroku-metrics"
More information at devcenter.heroku.com/articles/language-runtime-metrics.
Enable Ruby Language Metrics
To provide more visibility into the Ruby runtime, the Ruby language metrics feature surfaces additional language-specific time series metrics within Application Metrics. Ruby metrics include free and allocated heap object counts and number of free memory slots.
heroku labs:enable "ruby-language-metrics"
More information at devcenter.heroku.com/articles/language-runtime-metrics-ruby.
Set Ruby GC heap Growth Factor
When it comes to memory utilization you can control how fast Ruby allocates memory by setting RUBY_GC_HEAP_GROWTH_FACTOR. This value is different for different versions of Ruby. To understand how it works it is helpful to first understand how Ruby uses memory.
heroku config:set RUBY_GC_HEAP_GROWTH_FACTOR=1.03
More information at devcenter.heroku.com/articles/ruby-memory-use#gc-tuning.
Rails Autoscale Add-on
RailsAutoscale is one of the must have add-ons for Heroku. It lets you scale your web and worker dynos up and down based on queue time. So besides helping your application scale, it can also save you a lot or money.
More information at elements.heroku.com/addons/rails-autoscale.
Scout APM Add-on
Scout APM is another must have add-on for Heroku. It helps find N+1 queries, slow database queries, memory bloat and more.
More information at elements.heroku.com/addons/scout.
Choosing Your Dynos
I highly recommend you read How many Heroku dynos do you need, and which size—An opinionated guide from railsautoscale.com. Adam does a great job explaining and recommending different dyno types, as well as their ideal settings for scaling.
More information at railsautoscale.com/how-many-dynos/.
Heroku Commands
And finally some handy commands for Heroku.
- Server Deploy
git push heroku main
- Server Logs
heroku logs --tail
- Server Restart
heroku restart
- Rails Console
heroku run rails console
- Postgres Info
heroku pg:info
- Postgres Diagnose
heroku pg:diagnose
- Maintenance On
heroku maintenance:on
- Maintenance Off
heroku maintenance:off
- Database Drop
heroku pg:reset DATABASE
- Database Migrate
heroku run rake db:migrate
- Database Seed
heroku run rake db:seed
Are there other Heroku settings or optimization you like to make? I'd love to hear from you in the comments!
Top comments (0)