Improving Rails Performance by Optimizing Phusion Passenger

I upgraded my Linode instance to 4 GB (free upgrade). The server was up for 513 days. The downtime was only 6 minutes for the upgrade process to complete. Before the upgrade, the server was using close to 2 GB for running Phusion Passenger, MySQL, Redis and ElasticSearch. Now, I have extra 2 GB, it's time to figure out how to use it to improve performance.

Memory Usage

To examine memory usage of Phusion Passenger, run:

$ passenger-status
Version : 5.1.2
Date    : 2017-05-08 20:03:46 +0000
Instance: DyzFK0Jy (Apache/2.2.22 (Ubuntu) Phusion_Passenger/5.1.2)

----------- General information -----------
Max pool size : 3
App groups    : 1
Processes     : 1
Requests in top-level queue : 0

----------- Application groups -----------
/srv/myrailsapp/current (production):
  App root: /srv/myrailsapp/current
  Requests in queue: 0
  * PID: 4337    Sessions: 0       Processed: 56      Uptime: 14m 14s
    CPU: 0%      Memory  : 121M    Last used: 38s ago

You can see 14 minutes after the upgrade, the server is using 121 MB of RAM. It is using only one processes.

Number of CPUs

To check number of CPUs:

$ cat /proc/cpuinfo

processor   : 0
vendor_id   : GenuineIntel
cpu family  : 6
model       : 62
model name  : Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz
stepping    : 4
microcode   : 0x1
cpu MHz     : 2799.994
cache size  : 4096 KB
physical id : 0
siblings    : 1
core id     : 0
cpu cores   : 1
apicid      : 0
initial apicid  : 0
fpu     : yes
fpu_exception   : yes
cpuid level : 13
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl eagerfpu pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm fsgsbase tsc_adjust smep erms xsaveopt arat
bugs        :
bogomips    : 5602.32
clflush size    : 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual
power management:

processor   : 1
vendor_id   : GenuineIntel
cpu family  : 6
model       : 62
model name  : Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz
stepping    : 4
microcode   : 0x1
cpu MHz     : 2799.994
cache size  : 4096 KB
physical id : 1
siblings    : 1
core id     : 0
cpu cores   : 1
apicid      : 1
initial apicid  : 1
fpu     : yes
fpu_exception   : yes
cpuid level : 13
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl eagerfpu pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm fsgsbase tsc_adjust smep erms xsaveopt arat
bugs        :
bogomips    : 5602.32
clflush size    : 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual
power management:

I have 2 CPUs, so I need to benchmark to see if I increase the processes to 2, whether it will improve the performance or not.

Calculate Number of Processes

Before we can optimize Rails app for performance, we must answer questions such as:

  1. Is the Rails app running in single threaded mode or multi-threaded mode?
  2. Is it CPU or IO intensive?

You can view the graph of CPU, Memory, I/O, Network and Disk usage to decide.

CPU, Memory, I/O and Disk Usage

The multi-process formula for single-threaded apps:

max_app_processes = (TOTAL_RAM * 0.75) / RAM_PER_PROCESS

Let's say we can use 2 GB of memory for elasticsearch, database etc. So, we can use 50% (remaining 2 GB) of the memory for passenger, so:

max_app_processes = (TOTAL_RAM * 0.50) / RAM_PER_PROCESS

Let's assume, step 1 result over a period of time results in 200 MB usage.

max_app_processes = (4 GB * 0.50) / 200 MB
= 4000 * 0.5 / 200 = 2000 / 200 = 10

It is a good idea to see what happens to the performance when the number of processes is changed from 1 to 2 then 4 and so on. This will tell us what value is ideal for my Rails app.

References


Related Articles


Create your own user feedback survey