Guide: WordPress with Maximum Performance and Speed

This is a step by step guide in which I will show you how to setup WordPress with maximum speed and performance for just $15 per month utilizing Nginx + PHP-FPM + APC + Cloudflare + Redis. It is the same that this blog is using and I will show you how. No need for any caching plugins!

WPengine.com will charge you $249 per month for something similar but I am 100% certain my unique solution will outperform them any time of the day.

Summary

Instead of Apache we will use Nginx which is way, way more faster. PHP-FPM Is much faster than normal PHP. APC will cache all the PHP in the internal RAM memory so it does not need to be compiled everytime. CloudFlare will take care of some client side optimization as well as acting as a content delivery network for static files and we will use Redis as a front end cache to output HTML.

Out of the box settings

This guide does not contain any firewall settings, security or any change of settings. I used all the default ones for this blog and it works very well.

Step 1: Get a good VPS

Get a good VPS and choose Debian 6, 32 bit.

After quite some research I went for 6syns, order here and the nano package for $15/month should be ok. Their name servers are ns1.6sync.net, ns2.6sync.net and ns3.6sync.net. Important! Place your website on a server in the same country as your target audience. The difference in added latency can be more than 100ms!

Download Putty and connect to your server.

Step 2: Installation of Software

Run the following commands:

passwd cd .. nano /etc/apt/sources.list

Add the following two lines (see here):

deb http://packages.dotdeb.org squeeze all deb-src http://packages.dotdeb.org squeeze all

wget http://www.dotdeb.org/dotdeb.gpg cat dotdeb.gpg | apt-key add - rm dotdeb.gpg apt-get update apt-get upgrade apt-get install php5 php5-fpm php-pear php5-common php5-mcrypt php5-mysql php5-cli php5-gd php-apc apt-get install nginx apt-get install redis-server apt-get install mysql-server mysql-client

Open the file php.ini like this:

nano /etc/php5/fpm/php.ini

And add the following 2 lines at the bottom:

extension=apc.so cgi.fix_pathinfo = 0

Continue the commands and replace website.com with your own domain:

cd .. cd var/www/website.com wget http://wordpress.org/latest.tar.gz tar -zxvf latest.tar.gz mv wordpress/* /var/www/website.com/ rmdir wordpress rm latest.tar.gz mysql -u root -p CREATE DATABASE wordpress; GRANT ALL PRIVILEGES ON wordpress.* TO [email protected] IDENTIFIED BY '[YOUR_PASSWORD]' WITH GRANT OPTION; quit

Step 3: Change the Nginx config file

You now have to edit the file etc/nginx/nginx.conf.

This is the one this blog is using (single website on the server and no Multi-Site) and it works well (change the domain name and the IP numbers):

user www-data; worker_processes 4; pid /var/run/nginx.pid; events { worker_connections 1024; # multi_accept on; } http { ## # Basic Settings ## sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 2; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; #access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; access_log off; gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; ## # Virtual Host Configs ## index index.php; ## See here: http://wiki.nginx.org/WordPress server { ## Your IP number goes here: listen 204.62.14.112; ## Below 3 lines will redirect non-www to www if ($host != 'jimwestergren.com' ) { rewrite ^/(.*)$ https://www.jimwestergren.com/$1 permanent; } ## Your website name goes here. server_name www.jimwestergren.com; ## Your only path reference. root /var/www/jimwestergren.com; location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } location / { # This is cool because no php is touched for static content try_files $uri $uri/ /index.php; } location ~ .php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~* .(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off; } } }

Restart PHP and Nginx to reflect changes to the config file:

/etc/init.d/php5-fpm restart /etc/init.d/nginx restart

Links to more info about this file:

Step 4: Edit the wp-config.php file

Just edit the wp-config.php file like you normally do when installing WordPress. More info on this link.

Check now so that your blog is working fine before going further.

Step 5: Redis as a front end cache for WordPress

Redis is an advanced key-value store. Like memcached on steroids. Everything is in the RAM and you can reach around 100 000 GET per second with Redis. We will cache all the HTML output in Redis and display it without the need to load WordPress.

Read and follow my article: How to load WordPress in a few milliseconds using Redis

Step 6: CloudFlare

Go and setup CloudFlare for your website. You get a content delivery network of your static files for free and some client side optimization as well + much more.

if you have any doubts, see my article: Why I recommend CloudFlare and why you should try it too

Credits and further reading

25 Oct 2012

Other posts