🚀 Best practices for running Rails in production
This guide covers different concepts you should be familiar with. Recommendations come from personal experience and work at Instacart. A few of the open source projects are ones I’ve created. For a comprehensive list of gems, check out Awesome Ruby.
Everyone writing code must be responsible for security. Best practices
Use an error reporting service like Rollbar.
Use Safely to rescue and report exceptions in non-critical code.
Use a centralized logging service like LogDNA.
Use Lograge to reduce volume.
gem 'lograge'
Configure it to add request_id
, user_id
, and params
.
# config/environments/production.rb
config.lograge.enabled = true
config.lograge.custom_options = lambda do |event|
options = event.payload.slice(:request_id, :user_id)
options[:params] = event.payload[:params].except("controller", "action")
options
end
# app/controllers/application_controller.rb
def append_info_to_payload(payload)
super
payload[:request_id] = request.uuid
payload[:user_id] = current_user.id if current_user
end
Use an auditing library like Audited.
Use Strong Migrations to catch unsafe migrations at dev time.
There are two important metrics to track for web servers.
Use a high performance web server like Puma.
Use Rack::Deflater for compression.
Use a CDN like Amazon CloudFront to serve assets.
Use Slowpoke for request timeouts.
Use a high performance background processing framework like Sidekiq with ActiveJob.
Use ActiveJob::TrafficControl to:
- quickly disable jobs
- throttle
- limit concurrency
BadJob.disable!
- Use an uptime monitoring service like Pingdom or Uptime Robot - monitor web servers, background jobs, and scheduled tasks
- Use a performance monitoring service like New Relic or AppSignal
- If you use Postgres, PgHero can help identify issues
- Use Marginalia to track the origin of SQL queries
- requests by action - total time, count
- queue time - X-Request-Start header
- jobs by type - total time, count
- requests by type - total time, count
- CPU usage
- space
- requests by type - total time, count
Use Notable to track notable requests and background jobs.
- errors
- slow requests, jobs, and timeouts
- 404s
- validation failures
- CSRF failures
- unpermitted parameters
- blocked and throttled requests
One very important place is ActiveRecord. Add to config/database.yml
and adjust as needed.
production:
connect_timeout: 1
checkout_timeout: 5
variables:
statement_timeout: 5000 # ms
production:
connect_timeout: 1
read_timeout: 1
write_timeout: 1
checkout_timeout: 5
variables:
max_execution_time: 5000 # ms, for MySQL 5.7.8 or higher
max_statement_time: 5 # sec, for MariaDB 10.1.1 or higher
Use an analytics service like Google Analytics or Mixpanel.
And possibly an open source library like Ahoy.
Use a feature flipper library like Rollout to easily enable and disable new features without pushing code.
Have suggestions? Help make this guide better for everyone.
Also check out best practices for developing with Rails.
If you use Heroku, check out Rails on Heroku.