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
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
Therefore Heroku recommends to use Puma in production
Infact, dev.to (this blogging platform) is hosted on Heroku and uses Puma in production
Puma is already battle tested by Heroku, Recently Gitlab also migrated to Puma from Unicorn
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:
536 requests per second
Puma benchmark:
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:
9 requests per second
Puma benchmark:
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.
Top comments (2)
It would have been nice to see nginx configs for each case.
Also I would add that setting up Passenger is orders of magnitude easier that setting up Puma.
Great post! Thanks for sharing 🙏