What the hell am I doing wrong? Slow times: 4.9 req/sec

Hi,

I switched to Linode (512) a couple of days ago from shared hosting (HostMonster).

After 3 days of work I managed to perfectly install a Wordpress site running on CentOS 6, Nginx, PHP-FPM, MySQL. I decided to test the speeds and compare the same identical sites: one running on Linode servers and the other on HostMonster servers.

Note: this website gets a "Grade A" on Yslow and "Overall performance score 96". I don't use any caching plugins (W3TC, WPSC, DB Cache) for Wordpress. I know I can make it load faster if I do. And if I run the website through Cloudflare. I'm not looking for that kind of replies to this thread…

I did some tests with Apache bench (4 x 200). The results are:

4.5 – 4.9 requests per second

~800 ms time per request

and takes around 40 seconds to complete

And for the shared hosting:

2-3 requests per second

~1400 ms time per request

and it takes around 90 seconds to complete

"It's great" you'd say, "it's around twice as fast". But real testing shows different results (using http://whichloadsfaster.com):

Over 50 runs an improvement of only 15% (1426ms average HostMonster | 1227ms average Linode)

And it's not only these tools. I also feel that they load the same!

Is that normal? From what I read over the Internet about nginx and PHP-FPM I expected much better results.

There is also the cost: I pay 3.3 times more ($6 over $20), get bandwidth cap, endless headaches (SSH noob) for trying to setup a server myself, for only ~15% improvement? I switched hoping my websites would load faster! Am I doing something wrong here?

So, I am asking you to help me!

I do want to like Linode! I do presume it's not their fault! But if things stay the same I don't see me staying here… :(

Are there any nginx tricks you could recommend me to make this setup somehow faster? Should I mess with the HTTPD.conf at all? What else?

Thanks for your time!

P.S. I am attaching below (irrelevant code is missing, for the sake of length) the nginx.conf file, single website conf file and my httpd.conf (both improved from what I read over the Internet). In the php.ini I didn't change anything except allow for larger files to be uploaded via PHP (20MB):

=======

nginx.conf

=======

user  nginx;
worker_processes 4;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    client_max_body_size 20M;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile on;
    tcp_nopush off;
    tcp_nodelay on;

    #Improved security (allow only 5 connections, timeout faster, limit buffer size)
    limit_zone slimits $binary_remote_addr 5m;
    limit_conn slimits 5;
    client_body_timeout 10;
    client_header_timeout 10;
    keepalive_timeout 30;
    send_timeout 10;
    client_body_buffer_size 3K;
    client_header_buffer_size 3k;
    large_client_header_buffers 2 1k;

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_disable "MSIE [1-6].(?!.*SV1)";
    gzip_comp_level 2;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
    include /etc/nginx/blockips.conf;
}

=====

single_website.conf

=====

    location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
        access_log        off;
        expires           30d;
        root /srv/www/sicanstudios.com;
    }

    location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    }

=====

httpd.conf

=====

Timeout 30
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 6
 <ifmodule prefork.c="">StartServers       8
MinSpareServers    5
MaxSpareServers    20
ServerLimit        512
MaxClients         512
MaxRequestsPerChild  4000</ifmodule> 
# worker MPM (commented out)

15 Replies

Assuming your site is http://www.sicanstudios.com/ then you're not using nginx you're using apache, and if your httpd.conf is the one being used you're using apache prefork.

Also if you haven't already install php-apc.

I know, that's the website hosted on HostMonster (Apache+PHP5+MySQL+Wordpress)

Php-Apc was my next move. I just wanted to compare the different websites mano-a-mano

A pointer to your new site would help when testing it.

It's http://uniteaccommodation.co.uk/

(though the menu links are for the old website)

Ok I did some ab tests:

50 requests, 5 at a time

New site

Requests per second: 4.15 #/sec

Old site

Requests per second: 2.64 #/sec

Seems good to me.

How many php children do you have fpm spawning? Install apc and I'll bench again.

@sican:

Php-Apc was my next move. I just wanted to compare the different websites mano-a-mano

That's not mano a mano. AFAIK all shared hosts use some kind of opcode cacher. Back in the day I was on shared host they all had Zend or eAccelerator.

Plus they have probably have much stronger machines and more cores thrown at the shared hosting environment.

So running your own Linode you actually DO have benefits:

1. Entire node RAM is yours to use as you see fit (no shared hosting limits there)

2. Guaranteed bandwidth really is guaranteed, no one will kick you out if you consistently spend 200GB per month (for smallest node)

3. Root access to configure and install ANY PHP module you require in whatever configuration

4. Configure and tune the DB for your needs and usage patterns

5. Use memcached or APC for those apps that support them (Drupal, SMF, I don't know if Wordpress does, my last contact with PHP apps was many moons ago)

6. Secure, virtualized environment, you don't depend on your shared host sysadmin to properly configure open basedirs or whatever, because some shared hosts might run your PHP as your account user, most won't. Wasn't there recently a breach into a major shared hosting environment, I think it was an Australian company (too lazy to look it up now)…

Using a VPS does not necessarily make your site load faster. The shared server you were on probably had much more powerful physical processors than the virtual CPUs that you get here. When there isn't much congestion, shared hosting can even be faster than a VPS. HostMonster is a large and reputable host, so I'm sure they use monstrously powerful servers to host their customers and do everything they can to prevent some customers from slowing down the entire server. Unless you're the one who's getting suspended for excessive server load, this is a pretty neat arrangement.

The benefit of a Linode is not raw speed, but the fact that whatever speed you currently get is guaranteed. You won't experience slowdowns just because somebody else is getting slashdotted. Whether that's worth $19.95 is for you to decide. You also get a lot more control over the server, but again, whether or not that counts as a good thing depends on what you want to do with your server.

WordPress being the big bloated ogre it is, a 15% improvement in speed is roughly in the ballpark of what I'd expect the difference between a reputable shared host and an untuned linode to be.

A shared host optimizes a lot of things to squeeze out every bit of performance out of their hardware. You should do the same on your VPS. Installing APC will probably bring up the difference to at least 50%. Fine-tuning MySQL is the next step, because WordPress relies very heavily on the database. Good shared hosts use extremely well-optimized MySQL settings. There are MySQL tuning scripts out there. Use them. Switch to InnoDB if you haven't already done so, and read up on InnoDB configuration parameters.

Thanks for the replies guys!

I instlaled APC and it's already better, at around 6.5 requests per second!

Next step would be db optimisation!

Will post a reply here when I finish with it…

for mysql check out http://mysqltuner.pl/mysqltuner.pl and https://launchpad.net/mysql-tuning-primer

@hybinet:

Switch to InnoDB if you haven't already done so, and read up on InnoDB configuration parameters.

Why?

Just a quick update: I optimised MySQL and enabled caching.

New test shows:

240 requests per second

~16ms time per request

and takes around 0.83 seconds to complete

Second time Apache Bench run:

1268 requests per second

~3.1ms time per request

and takes around 0.158 seconds to complete

Using http://whichloadsfaster.com shows:

Over 50 runs an improvement of 380% (3.8x faster) (1285 ms average HostMonster | 341 ms average Linode)

That looks much better.

Regarding innodb vs the default myisam. Innodb handles crashes better always a good thing and supports transactions. From a tuning point of view it's also easier since it has less options to tune, basically set a decent buffer pool and you're done.

@obs:

Regarding innodb vs the default myisam. Innodb handles crashes better always a good thing and supports transactions. From a tuning point of view it's also easier since it has less options to tune, basically set a decent buffer pool and you're done.

Yes, but the app must be written to support transactions, and I don't know if Wordpress is. Otherwise you have implicit transactions, meaning each query is an independent one which makes it no different than MyISAM but with additional overhead.

As for handling crashes better… could be. I left myisam for transactional Postgres (which, flamebait or not, runs circles around InnoDB) many moons ago after persistent index file corruption required weekly restores from the backup…

@Azathoth:

I left myisam for transactional Postgres (which, flamebait or not, runs circles around InnoDB) many moons ago after persistent index file corruption required weekly restores from the backup…
I love PostgreSQL too. I wouldn't use any other RDBMS for a new project. But since WordPress can't use PostgreSQL, InnoDB seems to be the next best option even if no transactions are used. At least the tables will be much more corruption-resistant, and reading while writing is also going to be faster.

@hybinet:

@Azathoth:

I left myisam for transactional Postgres (which, flamebait or not, runs circles around InnoDB) many moons ago after persistent index file corruption required weekly restores from the backup…
I love PostgreSQL too. I wouldn't use any other RDBMS for a new project. But since WordPress can't use PostgreSQL, InnoDB seems to be the next best option even if no transactions are used. At least the tables will be much more corruption-resistant, and reading while writing is also going to be faster.

And as I understand it, InnoDB has row-level locking whereas MyISAM has table-level locking. So, InnoDB should be faster for a situation where you have many read/writes going on. Not sure if that would have much of an impact on Wordpress though, unless it's a Wordpress site that publishes many posts/day.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct