Phusion Passenger Optimizations

In a previous article, we installed and tested a baseline configuration of Phusion Passenger, aka mod_rails. In this post, we’ll be comparing memory usage and performance by varying Apache configuration settings in httpd.conf.

Realize that these numbers aren’t absolutes and will vary on your server, depending on its architecture, CPU, and RAM. Our VPS slice has the following specs:

  • Linux Fedora 8, 64-bit
  • 512MB RAM
  • Rails 2.0.2
  • Phusion Passenger 2.0.1
  • Enterprise Ruby 1.8.6 patchlevel 11

We used Apache Bench from the command line for testing:

# ab -n 10000 -c 100 http://server/app_path

PassengerMaxPoolSize

PassengerMaxPoolSize specifies the maximum number of Ruby on Rails application instances that may be simultaneously active. This setting has a lot of bearing on overall memory consumption and performance.

Memory Usage

PassengerMaxPoolSize    total       used       free     shared    buffers     cached
        1              524460     417040     107420          0      21384     120216
        2              524460     454740      69720          0      22560     127080
        3              524460     489692      34768          0      23160     131860
        4              524460     494548      29912          0      19860     110868
        5              524460     516772       7688          0      19100     103628

Performance

PassengerMaxPoolSize         Requests per second 
        1                    89.09 [#/sec] (mean)
        2                   170.28 [#/sec] (mean)
        3                   224.88 [#/sec] (mean)
        4                   274.94 [#/sec] (mean)
        5                   272.45 [#/sec] (mean)

You’ll notice that our sweet spot is when PassengerMaxPoolSize = 4, since we did not gain any more performance when set to 5, and less memory is used.

PassengerMaxInstancesPerApp

According to the docs, PassengerMaxInstancesPerApp is the maximum number of application instances that may be simultaneously active for a single application. The recommendation is to have the value be less than PassengerMaxPoolSize. Trying different values, ranging from 1 to 3, we observed memory consumption to be a bit less, however the number of requests per second also suffered. We found that setting the value to 0, or no limit, produced the best results performance-wise. If you’re experiencing heavy swapping on a smaller slice, on the other hand, capping this value at something between 0 and PassengerMaxPoolSize will help.

Things that May Affect Benchmarks

If you’re curious about seeing the impact of the above settings on your own configuration, be aware of the following.

Heavy Swapping

As physical memory is used up, your machine will start swapping virtual memory to disk. So be aware of any background processes already running. Disable any cron jobs, scheduled backups, etc.

Linux IP Tables

A software firewall like Linux IP Tables tracks each connection and temporarily persists a handle in a built-in database. It’s entirely possible to overwhelm the system, which will affect your numbers. Your Linux kernel log will show this message: “ip_conntrack: table full, dropping packet.” For an explanation of this issue and how to solve it, see this article.


About this entry