When it comes to picking a server for Ruby apps, I usually go with Puma. But I’ve tried the other big three too: Passenger, Thin, and Unicorn.

For a more in-depth analysis, I can recommend this and this article. For a not-so-in-depth-or-researched-and-mainly-just-opinionated point of view, carry on.

Passenger

I’ve found Passenger to be resource-heavy when the workloads are high. It starts creating a lot of processes and doesn’t let you switch over to the multi-threaded concurrency model in the free version.

I also don’t like Passenger’s fine integration into the web server i.e Nginx / Apache. I like to keep things separate - I want my web server isolated from my app server.

However if you’re starting with web/app servers and, say, serving your first Rails app, then Passenger can be an excellent starting point. It definitely simplifies things. For example, you can restart your application through touch /path/to/project/tmp/restart.txt

I should perhaps highlight that despite my opinion, Passenger is very popular. You should talk to a Passenger-enthusiast before you make the choice to not use it in production.

Thin

I’ve seen that most Mac devs use Pow in development while Linux devs are stuck with WEBrick. I keep switching between Mac and Linux so I can’t really use either one of them: Pow because it’s Mac-only and WEBrick because an actual brick would be a better choice.

I opt for Thin as my development server. It’s very resource friendly and it can be started in threaded mode. Most importantly, it supports command line options to initiate the server in SSL mode. This allows me to paint a picture closer to production when I’m developing a feature.

Without getting technical, let me point out that Thin is better than others when it comes to responding long running requests which makes it well suited for long polling.

Unicorn

Unicorn is great. It has served me well in many projects. However, it is best suited for fast clients e.g. simple calculation services or APIs.

As wonderful as it is though, I stopped using Unicorn. Puma’s setup is friendlier, in my opinion. Controlling Unicorn was also a challenge at times: often I copied somebody’s custom script to have a controllable Unicorn service.

However, it’s entirely possible that I was being quite, quite, stupid and there’s a much easier way to setup Unicorn for graceful control. If you use Unicorn and you’re happy with it, more power to you.

Puma

I think Puma is the best. The Rails team apparently thought so too and made it the default development server in Rails 5 (plus they wanted Action Cable to run in-process with the rest of the app).

The documentation is also very clear; an example is the clear distinction between different types of restarts and what their impact is.

Lastly, the configuration settings are easy to understand and controlling it is so easy with the pumactl commands.

I like to keep my Puma config specific to the live site(s) which is why I don’t use it in development.

Despite being such a wild cat, Puma is very easy to tame.

In the end, I’d like to leave a tip for anybody who is new to serving applications: you won’t find a single solution that covers all scenarios. I’ve found Puma to be suitable for most of my projects only after trying out alternatives. Those options are still in the back of my mind for each new project. Any choice might be OK for initial setup but before you achieve the best results, you will have to experiment, learn, calculate, rinse, and repeat.

If you are still looking for a one-ring solution though, you should check out the upcoming HHMYC Server by clicking here.