Why to use PUMA in production for your Rails App

If you are still using Unicorn, Thin or Passenger open source application server in production then this post is for you.

Point to note that Passenger Enterprise is different from Passenger open source, this post only talks about Passenger open source.

This Blog Post has very good comparison about features provided by Unicorn, Puma & Passenger

Alt Text

Point to note in this comparison is that PUMA is multithreaded and Passenger is multithreaded in only Enterprise edition

If you believe that multithreaded server is of no use because Ruby has GIL then you should read below snippet from Heroku Blog

Alt Text

Therefore Heroku recommends to use Puma in production 

Alt Text

Puma is already battle tested by Heroku, Recently Gitlab also migrated to Puma from Unicorn 

Alt Text

Read about Gitlab migration journey here

Puma really outshine other options when your application is dependent on lots of I/O operations.

I did some benchmark to compare Passenger open source & Puma performance

Configuration used during benchmarking

Passenger gem:

  • Version: 6.0.5
  • Workers count: 6 (Default)

Puma gem:

  • Version: 4.3.5
  • Workers count: 4
  • Threads count: 5 *5 threads per worker

Machine: 
macOS Catalina, Dual-Core Intel Core i5, 8GB RAM

Benchmarking tool and configuration

Tool used: https://github.com/wg/wrk
Configuration:

  • Threads: 2
  • Connections: 100
  • Duration: 30 sec

When I/O operations are minimal

homes.json API perform one DB query and return back json data

Passenger benchmark:

Alt Text

536 requests per second

Puma benchmark:

Alt Text

883 requests per second

Take away
64% increase in number of requests served per second
Puma can serve 10,000 more requests in 30 seconds

When I/O operation increases

homes/1.json API performs 2 operations, one DB query and one network call and then return back json data
Network call is HTTP.get('https://facebook.com')

Passenger benchmark:

Alt Text

9 requests per second

Puma benchmark:

Alt Text

29 requests per second

Take away
Puma is 3x faster
Puma can serve 600 more requests in 30 seconds

How to set correct thread and worker count for Puma

Every Application is different therefore there is no universal Puma config which everyone can use.
You will have to try different combination of threads and workers count to find out which one is good for your application.
I created one gem https://github.com/anilmaurya/puma-benchmark which can help you in finding correct thread and worker count for your application.

RefERENCES

  1. https://deliveroo.engineering/2016/12/21/unicorn-vs-puma-rails-server-benchmarks.html
  2. https://www.toptal.com/ruby/ruby-concurrency-and-parallelism-a-practical-primer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.