Jim Westergren
A blog about me, my projects, SEO, Web Development and Personal Development.
"If we did all the things we are capable of, we would literally astound ourselves." - Thomas A. Edison

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.


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:

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:

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

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:

		## 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_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

Comments powered by Disqus
About the Author Jim Westergren Jim Westergren is a Swedish web entrepreneur. He is happily married and has two lovely children. Some of his interests are web development, SEO and writing. He is the Founder and owner of TodaysWeb offering SEO, web development and manages projects such as DomainStats and N.nu. Read his . Follow Jim on Twitter.

Design, text and CMS (N.nu) by myself.