Overview
Puma is an application web server for Ruby that supports multi-threading and multi-processing. It’s the default server for Rails and excels at handling many concurrent connections with modest memory usage.
Setup
To install run gem install puma.
Or add it to your Gemfile:
# Gemfile
gem 'puma'Starting Puma
Start Puma from the command line:
# Start with defaults (0.0.0.0:9293)
puma
# Specify host and port
puma -b tcp://0.0.0.0:3000
# Run in the background
puma -dFor Rails applications, Puma is started via:
bundle exec rails serverConfiguration
Create a config/puma.rb file for production-ready settings:
# config/puma.rb
# Number of worker processes
workers Integer(ENV.fetch("WEB_CONCURRENCY") { 2 })
# Threads per worker
threads_count = Integer(ENV.fetch("RAILS_MAX_THREADS") { 5 })
threads threads_count, threads_count
# Bind to port
port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
# Preload the application before forking workers
preload_app!
# Restart workers gracefully
on_worker_boot do
ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
endWorkers vs Threads
Puma offers two concurrency models:
- Workers — separate processes (multi-processing). Each worker forks from the main process. Good for CPU-bound work. Set with
workers N. - Threads — run within each worker (multi-threading). Good for I/O-bound work (database queries, HTTP calls). Set with
threads min, max.
For a typical Rails app, start with:
workers: 2
threads: 5 per worker
Daemon Mode
To run Puma as a daemon:
puma -d -p 3000To stop a daemonized Puma process:
pumactl stopHealth Checks
Puma provides a control app for status and health checks:
# config/puma.rb
activate_control_app "tcp://127.0.0.1:9293", auth_token: "secret"pumactl -S /path/to/puma/state statusSource
Source is found at github.com/puma/puma.