Take the 2-minute tour ×

I have a PHP file that gets HTML from Memcached and serves it to the user. When I test it like this:

ab -n 1000 -c 100 http://website.com/test.php

It does 22 requests per second.

But when I put the same HTML to an HTML file and do this test:

ab -n 1000 -c 100 http://website.com/test.html

I get like 4500 requests per second.

I need to stick to PHP because the first time I need to generate HTML, and the next times I just get the generated one from Memcached. And moreover the HTML I display is different for every other user (recognized based on $_GET ['user_id'] value). Is there any way to make RPS higher? Closer to serving plain HTML?

I use lighttpd as the web server.

share|improve this question
Are you sure that those responses come from the cache? –  Gumbo Sep 30 '09 at 9:57
@Gumbo Yes, i've checked it. –  tomaszs Sep 30 '09 at 9:59
"How much" PHP do you need for the $_GET['user_id']related part of the page and "how important" is the improvement in speed? Did you also test only serving the memcache part - only that nothing else? How many PHP processes/backends where running when you did the ab -c 100 test? –  VolkerK Sep 30 '09 at 10:13
@VolkerK I do not understand what do you mean by "how much, how important" part. Could you explain it to me? When I run ab -c 100 I had 10 lighttpd processes and 100 php-cgi processes. –  tomaszs Sep 30 '09 at 10:21
In a comment to your previous question ( stackoverflow.com/questions/1496987/… ) you said "Because when I published this app last time I had 10k concurrent requests" and I just wanted to know what you'd be willing to do to get the performance up. Maybe (just maybe, we're not there yet I think ;-)) even something like switching from php to a C-plugin for lighthttpd? –  VolkerK Sep 30 '09 at 10:30
show 1 more comment

4 Answers

up vote 3 down vote accepted

Chain of thoughts (to be continued....):
First I would test if the problem is triggered by or significantly worsened by concurrency. With your -n 1000 -c 100 test you had a ratio of 22/4500. What about -n 1000 -c 10 or -n 1000 -c 1?

Then I would try the same again + keeping track of memory consumption, disk I/O and CPU usage. Is any of this clearly the limiting factor?

Then I'd test simple PHP scripts:

  • an empty script
  • <?php echo 'x';
  • no script at all, but the contents of test.html copied over to test.php
  • only serving a small Memcached item. As simple a script as possible, construct the Memchached object and get an item, no test, no expiration, no add, only echo $mc->get(string $key)

How do those compare to test.html?


Let's take Web Server Performance Comparison: LiteSpeed 2.0 VS as a comparison point. The benchmark was performed "for" another "rivaling" webserver product but for the moment let's assume they weren't (too) biased ;-)

They had a

  • CPU: Single Intel Xeon 2.4 GHz/533 MHz FSB/512 KB L2 Cache
  • Memory: 256 MB ECC PC2700
  • Hard Drive: 36 GB 10K RPM SCSI drive Seagate ST336607LW
  • NIC: on board Intel PRO/1000 Gigabit Adapter

The lighthttpd served 15475 files per second of 100 bytes, scripts helloworld.php 1593 times per second and phpinfo.php 399 times per second (both FastCGI). That's a ratio of ~ 1:10 (hello world) or 1:40 (phpinfo). "Your" ratio is 22:4500 ~ 1:200. And even stranger it doesn't change when the script changes. Your "real" script or an empty PHP script, no matter always 1:22. That raises the "strangeness factor" quite a bit (even though the tests are not identical).

First of all I would double-check if PHP was compiled with FastCGI support, see http://www.fastcgi.com/docs/faq.html#PHP. Then I'd test "my" lighthttpd with a simple C/C++ FastCGI program as mentioned in the test, a real simple "hello world". There's an example at http://www.fastcgi.com/devkit/doc/fastcgi-prog-guide/ch2c.htm#4263. If this scales "well", i.e. significantly better than your PHP FastCGI, I'd try it with a "barely running" PHP version, i.e. compiled with --disable-all and only those modules (re)actived and built-in that are necessary to start PHP and let it print "hello world". Also use the default php.ini. Does this change anything?

share|improve this answer
Thank you for answer. Here are results: "-c 10" gives 22 RPS, "-c 1" both gives 21 RPS. CPU usage is max. 60% and Memory max. 300 MB from 2 GB available. I don't know how to measure disc i/o usage. In all 4 test scenarios bulleted out I get 22 RPS too. –  tomaszs Sep 30 '09 at 11:28
So this first series of tests had virtually no effect what-so-ever... –  VolkerK Oct 1 '09 at 9:41
Thanks for your help. You're right: it seems to be php/lighttpd problem. So as you write before I recompile php i would like to check if it's compiled actually with fastcgi. How to check it? –  tomaszs Oct 1 '09 at 13:31
In PHP 5.3 FastCGI is always enabled and cannot be disabled. Call your php executable from a shell with the -v parameter, e.g. php-cgi -v. It prints cgi-fcgi if fastcgi support is enabled and just cgi otherwise. –  VolkerK Oct 1 '09 at 14:36
@VolkerK as you wrote I took a closer look at fcgi. It occurred that Its not enabled but available at my system. So i used this: cyberciti.biz/tips/lighttpd-php-fastcgi-configuration.html to update config. Next it ocurrent that it uses /etc/php.ini not /home/domain.com/httpdoc/php.ini. So i've updated first to be like the second one. Next i've checked if it works. And it worked. I've tested test.php and have now 1500 RPS. It's 68x faster. Thank you very very much! Just great. I'm very happy and glad to get help from expert. Greetings and have a nice day!!! –  tomaszs Oct 1 '09 at 14:48
show 2 more comments

Going faster than script?

Try writing plain HTML files and serving those. And make an "updater" script that updates your HTML files from time to time, or on a certain event if you really need speed like that.

Try using SSI in some places and see how that works out (http://httpd.apache.org/docs/1.3/howto/ssi.html).

Try using Eaccelerator (http://eaccelerator.net/ ) or APC (http://www.php.net/apc/) to speed up the script parser, but it won't do wonders on PHP5...

Make sure the physical server has enough free resources (FAST hard drive, lots of RAM, multiple-processors).

It's pretty normal that your script is slower than the HTML page:) Serving up the HTML page means a simple copy-of-the-file-over-the-wire. The PHP script means initializing the script engine, caching, parsing classes, functions, memory allocations, session locking/unlocking and saving, reading from the Memcached server, reading configuration files. For each of the requests.

share|improve this answer
See answer to VolkerK - it's even for empty PHP –  tomaszs Oct 1 '09 at 12:51
add comment

You might also want to consider putting a HTTP cache in front of your PHP server. This will reduce the load on your web server and will handle the re-sending of previously rendered pages for you.

See Varnish for example. Another option is Squid

Obviously these are not options if you are on shared hosting - in that case rendering to .html files is a great solution.

share|improve this answer
add comment

You could try (psuedo code):

if file myfilecache/$user_$request_$today.html does not exist 
then do
     format page 
     write page to myfilecache/$user_$request_$today.html
redirect to myfilecache/$user_$request_$today.html

The file system makes is a pretty good cache and lightpd will do the actual work of serving up the page.

share|improve this answer
add comment

Your Answer


