Guys, it has been a long over due post. I have finished tuning passenger long back but caught up with Diwali celebration.
Anyways generally I prefer simple and easily understandable configuration. So following configuration is as per my best knowledge and google findings. ;)
I have verified my configuration using ab - Apache HTTP server benchmarking tool. Also tried other tools such as Jmeter, httperf. I have also used passenger-memory-stats for finding rails instance size and passenger-status for finding number of request which are pending in global queue.
I have started passenger tuning using passenger nginx user guide. You will also find passenger-apache guide.
As I am using nginx, following configuration is with respect to nginx but same will applies for apache except some extra directives and syntax.
After digging into passenger tuning, I realized that passenger well configured for production. But still Based on nginx-passenger user guide I have collected following list of directive, which we can configure according to our needs.
Almost all of these directive has default value which is good enough for an applications. But there are some directive which very important to configure depending on our application environment.
1. passenger_max_pool_size :
The maximum number of Ruby on Rails or Rack application instances that may be simultaneously active. A larger number results in higher memory usage, but improved ability to handle concurrent HTTP clients.
The value should be at least equal to the number of CPUs (or CPU cores) that you have. If your system has 2 GB of RAM, then we recommend a value of 30. If your system is a Virtual Private Server (VPS) and has about 256 MB RAM, and is also running other services such as MySQL, then we recommend a value of 2.
I recomond you to find your application instance size using passenger-memory-stats and configure value of passenger_max_pool_size.
e.g. If your application instance size is 300 MB and RAM size 2 GB then value of passenger_max_pool_size should be 4 because 1200 MB(4*300) will be used by application instance and remaning for other process.
2. passenger_max_instances_per_app :
The maximum number of application instances that may be simultaneously active for a single application. This helps to make sure that a single application will not occupy all available slots in the application pool.
This value must be less than passenger_max_pool_size. A value of 0 means that there is no limit placed on the number of instances a single application may use, i.e. only the global limit of passenger_max_pool_size will be enforced.
3. passenger_pre_start :
By default, Phusion Passenger does not start any application instances until said web application is first accessed. The result is that the first visitor of said web application might experience a small delay as Phusion Passenger is starting the web application on demand. If that is undesirable, then this directive can be used to pre-started application instances during Nginx startup.
This directive accepts the URL of the web application you want to pre-start. It may be specified any number of times.
1. A server with multiple rails applications (Development and test server)
I have a server with 16 GB of RAM and 8 core cpu, on which redmine(bug tracking system), test rails app and other developers app instances are running. Means you can say mutiple apps are running.
According to passenger-memory-stats redmine is taking 300 MB and other rails app 500 MB. So I have kept following configuration
On my production enviroment we have 8 GB of RAM and 4 core cpu, on which only single rails application is running.
As my rails application instance size is 500 MB, I have kept following configuration on production
Reference : http://www.alfajango.com/blog/performance-tuning-for-phusion-passenger-an-introduction/
Anyways generally I prefer simple and easily understandable configuration. So following configuration is as per my best knowledge and google findings. ;)
I have verified my configuration using ab - Apache HTTP server benchmarking tool. Also tried other tools such as Jmeter, httperf. I have also used passenger-memory-stats for finding rails instance size and passenger-status for finding number of request which are pending in global queue.
I have started passenger tuning using passenger nginx user guide. You will also find passenger-apache guide.
As I am using nginx, following configuration is with respect to nginx but same will applies for apache except some extra directives and syntax.
After digging into passenger tuning, I realized that passenger well configured for production. But still Based on nginx-passenger user guide I have collected following list of directive, which we can configure according to our needs.
Directive | Default Value | Nginx Block | Use |
---|---|---|---|
passenger_max_pool_size <integer> | 6 | http | Maximum instances on server |
passenger_pool_idle_time <integer> | 300 sec | http | instance idle time |
passenger_max_instances_per_app <integer> | 0 | http | Maximum instances allowed to single app |
passenger_min_instances <integer> | 1 | http, server, location, if | minimum number of application instances which are always active |
passenger_pre_start <url> | - | http | Pre start application |
passenger_use_global_queue <on|off> | on | http, server, location, if | Turns the use of global queuing on or off |
passenger_ignore_client_abort <on|off> | off | http, server, location, if | Ignore client aborts |
rails_framework_spawner_idle_time <integer> | 1800 sec | http, server, location, if | FrameworkSpawner server idle time |
rails_app_spawner_idle_time <integer> | 600 sec | http, server, location, if | ApplicationSpawner server idle time |
passenger_log_level <integer> | 0 (Can be 0, 1, 2, 3) | http | for how much information Passenger should write into error.log |
passenger_debug_log_file <filename> | error.log | http | allow to specify the file that debugging and error messages should be written |
passenger_pass_header <header name> | http, server, location, if | Used to pass headers |
Almost all of these directive has default value which is good enough for an applications. But there are some directive which very important to configure depending on our application environment.
1. passenger_max_pool_size :
The maximum number of Ruby on Rails or Rack application instances that may be simultaneously active. A larger number results in higher memory usage, but improved ability to handle concurrent HTTP clients.
The value should be at least equal to the number of CPUs (or CPU cores) that you have. If your system has 2 GB of RAM, then we recommend a value of 30. If your system is a Virtual Private Server (VPS) and has about 256 MB RAM, and is also running other services such as MySQL, then we recommend a value of 2.
I recomond you to find your application instance size using passenger-memory-stats and configure value of passenger_max_pool_size.
e.g. If your application instance size is 300 MB and RAM size 2 GB then value of passenger_max_pool_size should be 4 because 1200 MB(4*300) will be used by application instance and remaning for other process.
2. passenger_max_instances_per_app :
The maximum number of application instances that may be simultaneously active for a single application. This helps to make sure that a single application will not occupy all available slots in the application pool.
This value must be less than passenger_max_pool_size. A value of 0 means that there is no limit placed on the number of instances a single application may use, i.e. only the global limit of passenger_max_pool_size will be enforced.
3. passenger_pre_start :
By default, Phusion Passenger does not start any application instances until said web application is first accessed. The result is that the first visitor of said web application might experience a small delay as Phusion Passenger is starting the web application on demand. If that is undesirable, then this directive can be used to pre-started application instances during Nginx startup.
This directive accepts the URL of the web application you want to pre-start. It may be specified any number of times.
passenger_pre_start http://foo.com/; passenger_pre_start http://bar.com:3500/; passenger_pre_start http://myblog.com/store;
Let's get into live scenarios
1. A server with multiple rails applications (Development and test server)
I have a server with 16 GB of RAM and 8 core cpu, on which redmine(bug tracking system), test rails app and other developers app instances are running. Means you can say mutiple apps are running.
According to passenger-memory-stats redmine is taking 300 MB and other rails app 500 MB. So I have kept following configuration
passenger_max_pool_size 16; # arround 8 GB for rails application and remaning for other process passenger_pool_idle_time 150; # reduced idle time as multiple app are running passenger_max_instances_per_app 8; # since single app should not use whole pool size, but simuteniouly should handle mutiple requests2. A server with single rails application (Production server)
On my production enviroment we have 8 GB of RAM and 4 core cpu, on which only single rails application is running.
As my rails application instance size is 500 MB, I have kept following configuration on production
passenger_max_pool_size 10; # arround 5 GB for rails application and remaning for other process passenger_pool_idle_time 600; # Increased as it is production passenger_min_instances 2; # atlease two instances should in memory at any time passenger_pre_start http://myprodapp.com/; # pre start my instance at the time of nginx start instade on first requestFor testing whether required instances are forked or not use ab (Apache benchmark) as described above.
Reference : http://www.alfajango.com/blog/performance-tuning-for-phusion-passenger-an-introduction/