Puma

A high-performance web server for Ruby applications that supports multi-threading and multi-processing.

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 -d

For Rails applications, Puma is started via:

bundle exec rails server

Configuration

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)
end

Workers 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 3000

To stop a daemonized Puma process:

pumactl stop

Health 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 status

Source

Source is found at github.com/puma/puma.