If you’ve been managing a website or websites for long, then you probably know a thing or two about improving website speed, SEO optimization and performance and WordPress. If you don’t know any about the subjects above and you’ve been managing websites for sometime, then you probably need to spend sometime on them, because they are valuable to any webmaster.

So, here’s the main story:

I have been blogging for quite sometime now, and have tried almost everything to get my blog performance up, speed up my pages and improve my blog chances of getting a good spot on Google Search Engine Result Pages (SERP).

I have tried the two popular WordPress’ caching plugins (W3 Total Cache and WordPress Super Cache). I switched from Apache2 to Nginx and tried many performance boosting WordPress plugins and nothing has really satisfied me or lived up to my expectations.

I also tried CloudFlare and Google PageSpeed Service (CDN) services. Both are great services but they do have some downsides. CloudFlare may help speed up your websites, but also impact your Google AdSense income and the performance gains I got from CloudFlare wasn’t much better then what I managed to do without it.

Google PageSpeed Service is great, it but doesn’t work with custom URL over SSL or TLS (HTTPS). It may work with Google Apps, but there’s so much work involved.

The take away is no one solution will improve your website performance. If you need to boost your website, you may have to spend on good and quality host, pay for CDN services, invest in a good WordPress theme and limit the amount of plugins installed.

Or you can do what I have done below.

My solution

What I’ve noticed over time is the less WordPress plugins I installed the better my website. I am not saying all plugins are bad, but limit the plugins installed on your WordPress blogs. The worst plugins to stay away from are those that add extra CSS and JS files to your blogs.

Running less plugins also is a good idea because many seem to be the gateway through your security. I only run five (5) plugins and these five are extremely necessary or I’d find ways to cut them down to even less.

  • External links and Social Pages

I also try to avoid social pages and external links. Adding many of these social pages and links to your blogs will add extra HTTP/HTTPS calls to your pages. This could also slow down your website.

I find ways to add these pages without adding additional costs in terms of speed to my pages.

  • WordPress Themes

I’ve always used lighter and faster WordPress themes. I totally avoid bloated and heavy theme with tons unnecessary plugins and scripts.

  • Host and Domain

To speed up my blog and improve security, I host my blog on Google Compute Engine. Seems like GCE helps speed up my pages as well as brought my hosting cost down. Prior to GCE, I was hosting my blog on 1and1 and was paying twice as much as I’m paying now on GCE.

I also host my domain at Google Domains. Google offers free private domain registration and seems to speed up domain lookups. Loving it!

  • Webserver / Database

I switched from Apache to Nginx, switched from MySQL to MariaDB and my website speed is improved as well. Below, I’ll show you how I configured my Nginx webserver as well as other modules. Nginx is fast, but Nginx and PHP-FPM are faster together.

If you ever intend to run Nginx, don’t forget to run it with PHP-FPM. The combination is perfect. We run CentOS 7, Nginx, MariaDB, PHP-FPM and WordPress. To install these servers and services, read this post or click the link below.


Here’s how hour Nginx webserver is configured with HTTPS.

Our Nginx’s Configurations (Green highlighted section is SSL, and red is Caching with PHP-FPM)

user nginx;
worker_processes 1;
worker_rlimit_nofile 4096;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
use epoll;
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
charset UTF-8;
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 off;
error_log /var/log/nginx/error.log warn;

## Security
server_tokens off;
## Timeouts
client_header_timeout 20;
client_body_timeout 20;
send_timeout 20;
keepalive_timeout 30;
reset_timedout_connection on;

## Size limits
client_max_body_size 15m;
client_header_buffer_size 2k;
client_body_buffer_size 26K;
large_client_header_buffers 4 8k;
types_hash_max_size 2048;

## SSL Certifcates
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 4h;
ssl_session_tickets on;
ssl_prefer_server_ciphers On;
ssl_stapling on;
ssl_stapling_verify on;
resolver valid=300s;
resolver_timeout 10s;
add_header Strict-Transport-Security “max-age=31536000”;

## file caching
open_file_cache max=4096 inactive=5m;
open_file_cache_valid 2m;
open_file_cache_min_uses 1;
open_file_cache_errors on;

## General
ignore_invalid_headers on;
sendfile on;
tcp_nopush on;
tcp_nodelay on;

## Gzip Settings
gzip on;
gzip_static on;
gzip_disable “msie6”;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 512;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/css text/javascript text/xml text/plain text/x-component application/javascript application/x-javascript application/json application/xml application/rss+xml font/truetype application/x-font-ttf font/opentype applicatio
n/vnd.ms-fontobject image/svg+xml;

## PHP-FPM caching
fastcgi_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=CZONE:1024m inactive=240m;
fastcgi_cache_key “$scheme$request_method$host$request_uri”;
fastcgi_cache_lock on;
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
include /etc/nginx/conf.d/*.conf;


Our site’s configuration (Red highlighted section is caching with PHP-FPM)

server {
listen 80;
server_name _;
return 301 https://www.liberiangeek.net$request_uri;

server {
listen 443 ssl spdy;
spdy_headers_comp 1;
ssl on;
ssl_certificate /etc/nginx/ssl/ssl-bundle.crt;
ssl_certificate_key /etc/nginx/ssl/liberiangeek.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
server_name www.liberiangeek.net;
root /var/www/html;
index index.html index.php;
## Yoast WordPress SEO
rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last;
rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;

## favicon
location = /favicon.ico {
log_not_found off;
access_log off;

## robots
location = /robots.txt {
allow all;
log_not_found off;
access_log off;

## Good for WordPress permalinks
location / {
try_files $uri $uri/ /index.php?$args;

## Caching
location ~* \.(css|js|rss|png|jpg|jpeg|gif|ico|woff)$ {
expires max;
log_not_found off;
access_log off;
add_header Pragma public;
add_header Cache-Control “max-age=31536000, public”;

## PHP settings
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_ignore_client_abort off;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 90;
fastcgi_read_timeout 90;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;
fastcgi_cache CZONE;
fastcgi_cache_valid 200 301 302 240m;
fastcgi_cache_min_uses 3;

## WordPress
set $no_cache 0;
if ($request_method = POST) {
set $no_cache 1;
if ($query_string != “”) {
set $no_cache 1;
if ($request_uri ~* “(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)”) {
set $no_cache 1;
if ($http_cookie ~* “comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in”) {
set $no_cache 1;
add_header X-Cache $upstream_cache_status;

The highlighted sections above belongs to SSL (if you enable HTTPS) and caching with PHP-FPM. The setup above have worked great for me and my site performance is improved. You can copy and apply the same settings in your environment if you want.

For PHP-FPM settings, we run the below.

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; ‘ip.add.re.ss:port’ – to listen on a TCP socket to a specific address on
; a specific port;
; ‘port’ – to listen on a TCP socket to all addresses on a
; specific port;
; ‘/path/to/unix/socket’ – to listen on a unix socket.
; Note: This value is mandatory.
;listen =
listen = /var/run/php-fpm/php-fpm.sock

; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
; mode is set to 0660
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

pm.max_children = 100
; The number of child processes created on startup.
; Note: Used only when pm is set to ‘dynamic’
; Default Value: min_spare_servers + (max_spare_servers – min_spare_servers) / 2
pm.start_servers = 21
; The desired minimum number of idle server processes.
; Note: Used only when pm is set to ‘dynamic’
; Note: Mandatory when pm is set to ‘dynamic’
pm.min_spare_servers = 7
; The desired maximum number of idle server processes.
; Note: Used only when pm is set to ‘dynamic’
; Note: Mandatory when pm is set to ‘dynamic’
pm.max_spare_servers = 35
; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries. For
; endless request processing specify ‘0’. Equivalent to PHP_FCGI_MAX_REQUESTS.
; Default Value: 0
pm.max_requests = 1000

So, this how we are setup and as you can see, our pages are running faster when compared to many other websites online for cheap.