How do you configure Puma or Unicorn for optimal performance in production?

When deploying a Ruby on Rails application, choosing the right web server and configuring it correctly is crucial for performance and reliability. This guide will walk you through configuring Puma and Unicorn for optimal performance in production environments. For more on performance optimization, check out our guide on best practices for high-performing APIs in Rails.

Understanding Puma and Unicorn

Puma and Unicorn are popular web servers used in Ruby on Rails applications. While both are capable of handling multiple requests concurrently, they have different approaches. For more on server configuration, see our guide on configuring application to handle slow clients.

  • Puma is a multi-threaded server, making it suitable for apps that require concurrent request handling with lower memory usage.
  • Unicorn uses a multi-process model, which can offer better isolation and stability for CPU-bound applications but at the cost of higher memory usage.

Configuring Puma for Optimal Performance

Basic Configuration

To set up Puma for production, create a config/puma.rb file. For more on configuration, check out our guide on optimize Rails app for high traffic.

ruby
1# config/puma.rb
2
3# Set the number of threads to use per worker
4threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
5threads threads_count, threads_count
6
7# Set the number of workers (note: workers consume more RAM)
8workers ENV.fetch("WEB_CONCURRENCY") { 2 }
9
10# Preload application for better performance
11preload_app!
12
13# Specify the port Puma will listen on
14port ENV.fetch("PORT") { 3000 }
15
16# Specify the environment
17environment ENV.fetch("RAILS_ENV") { "production" }
18
19# Use a `tmp` file to store the state
20pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
21
22# Allow Puma to be restarted by `rails restart`
23plugin :tmp_restart
24

Tuning Performance

  • Threads and Workers: Adjust threads and workers based on your server's CPU and memory capacity. Higher numbers of threads use more CPU time, whereas more workers consume more memory. For more on performance tuning, see our guide on common performance bottlenecks in Rails applications.
  • Preload application: This setting loads your application before the workers are forked, which can reduce memory consumption through CoW (Copy-on-Write). For more on memory management, check out our guide on impact of instance vs local variables on performance.

Configuring Unicorn for Optimal Performance

Basic Configuration

To optimize Unicorn for production, use a config/unicorn.rb file. For more on memory management, check out our guide on debug memory leak in Ruby on Rails.

ruby
1# config/unicorn.rb
2
3worker_processes Integer(ENV["WEB_CONCURRENCY"] || 4)
4
5listen ENV.fetch("PORT") { 3000 }, :tcp_nopush => true
6
7timeout 30
8
9pid ENV.fetch("PIDFILE") { "tmp/pids/unicorn.pid" }
10
11preload_app true
12
13before_fork do |server, worker|
14 Signal.trap 'TERM' do
15 puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
16 Process.kill 'QUIT', Process.pid
17 end
18 defined?(ActiveRecord::Base) and
19 ActiveRecord::Base.connection.disconnect!
20end
21
22after_fork do |server, worker|
23 defined?(ActiveRecord::Base) and
24 ActiveRecord::Base.establish_connection
25end
26

Performance Considerations

Additional Tips for Production

Monitoring and Analysis

  • Implement monitoring tools to track server performance metrics.
  • Use tools to handle exceptions gracefully and ensure system reliability.
  • For monitoring strategies, check out our guide on Rails app performance monitoring techniques.

Scaling and Load Balancing

Consider using reverse proxies to distribute traffic, handle SSL termination, and improve load management efficiently. For more on load balancing, see our guide on load balancer role in high traffic Rails application setup.

Memory Management

Leverage the preload_app directive in both Puma and Unicorn to take advantage of CoW memory usage patterns, reducing the overall memory footprint. For more on memory optimization, check out our guide on avoiding debugging memory leaks in Rails.

Related Resources

Performance Optimization

Server Configuration

Memory and Background Jobs

Conclusion

Configuring Puma or Unicorn effectively can significantly enhance your application's performance in production. Whether you opt for the concurrent threading model of Puma or the process-based approach of Unicorn, each has its strengths. Tailor your setup based on your application needs and server resources.

Suggested Articles