views:

144

answers:

3

Sorry if this might seem obvious. I've monitored that a web request on my Rails app uses 30-33% of CPU every time. For example, if I load a web page, then 30% of CPU is used. Does that mean that my box can only handle 3 concurrent web requests, and will stall if there are more than 3 web requests (i.e. I'll get a 100% CPU)?

If so, does that also mean that if I want to handle more than 3 concurrent web requests, then I'll have to get more servers to handle the load using a load balancer? (e.g. to handle 6 concurrent web requests, I'll need 2 servers; for 9 concurrent requests, I'll need 3 servers; for 12, I'll need 4 servers -- and so on?)

+1  A: 

It's difficult to tell based on this information. It depends very much on the web server stack you're using and which environment you're running. Different servers (Mongrel, Webrick, Apache using various mechanisms, Unicorn) all have different memory characteristics. Different environments (development vs. test vs. production) all exhibit radically different memory usage characteristics.

Richard Cook
Thanks Richard. I've tried opening 4 pages at the same time (from different browsers), and the app stalls with a 100% CPU. I'm using Nginx and the app is fairly large (over 100 models). If I keep the app as it is without optimizing it, does that mean I'll need more servers to handle the CPU load?
sjsc
As per Henning's answer below, Apache/Nginx will queue up requests without stalling. If you need to handle more than the four simultaneous requests that are already fully pegging your CPU then you would need to load-balance across multiple servers. However, I would ask myself what the page is doing. Just because your application contains over 100 models doesn't mean that hitting the app's front page should perform database queries on all 100 data models. Have you determined where the majority of the page render time is taking place?
Richard Cook
Is it in database queries, rendering views/templates or is the controller stuck performing other application tasks?
Richard Cook
Thanks for the great insight Richard! Really appreciate it. I'm doing a mixture of both rending a page and performing some action on the app (for example, if I'm loading a page, it uses 30% CPU; if I'm uploading a file, it uses 30% CPU until the file is finished uploading).
sjsc
+2  A: 

Your Apache or Nginx in front of the Passenger will queue requests until a Passenger worker becomes available. You can limit the number of concurrent workers so your server never stalls (but new visitors will have to wait longer until it's their turn).

henning-koch
Thanks Henning! That sounds like a great idea. Thank you so much. How would I limit the number of concurrent workers? Is it modifying the "passenger_max_pool_size" to be 2 or 3?
sjsc
+2  A: 

I think you should start with load tests. I wouldn't trust manual testing that much. Load tests tell you how long the response takes for each client, and how many clients simply time-out.

Also you will be able to measure the improvements objectively for any changes that you make.

Look at ab, or httperf; there are many other tools available.

Stephan

Stephan Wehner
Thank you Stephan! I just started load testing. It definitely opened my eyes to how bad my code is. Thank you so much for the tip.
sjsc