Recommended Nginx Configuration for High Traffic WordPress on Small VPS (512 RAM)

Optimize NGINX

This is most important and main section of this topic. Let’s optimize LEMP server for max performance and security.

Toolbox

To check the result of optimization, I’m using siege, Google PageSpeed Insights and Pingdom Tools to check the default WordPress installed to prevent un-control third party scripts and styles which’s included in plugins and themes.

Enable gzip compression

You can enable gzip compression for CSS and JavaScript files also. Apart from that any text data, e.g. XML files will also benefit from gzip compression. However, never turn on gzip compression on images or any kind of binary data.

    # enable gzip compression
    gzip on;
    gzip_static on;
    gzip_min_length  1100;
    gzip_buffers  4 32k;
    gzip_types text/plain text/css application/javascript text/xml application/xml+rss;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.";
    # end gzip configuration

Most important lines are gzip on and gzip_types to turn on gzip compression and list of MIME-types for which you want to turn on compression.
gzip_disable "MSIE [1-6]\."; will turn off compression if the browser is Internet Explorer 6 and below.

Buffers

Another incredibly important tweak we can make is to the buffer size. If the buffer sizes are too low, then Nginx will have to write to a temporary file causing the disk to read and write constantly.

client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 2 1k;

Open File Cache

open_file_cache is one of those little thing that can do magic if you use Nginx with high traffic websites. If you have little traffic you may not see any performance difference, but if you serve a few hundred of mbits or a couple of GBits of traffic you may see a big change in your server performance.
Changing this setting, in my environment, brought performance up from 560k req/sec, to 904k req/sec. I recommend using some variant of these options, though not the specific values listed below.

    open_file_cache max=1000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;

[digitalocean]

Connection Timeout

Timeout can also drastically improve performance.

    # Timeout for keep-alive connections. Server will close connections after this time.
    keepalive_timeout 30;
 
    # Number of requests a client can make over the keep-alive connection. This is set high for testing.
    keepalive_requests 100000;

    # allow the server to close the connection after a client stops responding. Frees up socket-associated memory.
    reset_timedout_connection on;
 
    # send the client a "request timed out" if the body is not loaded by this time. Default 60.
    client_body_timeout 10;
    client_header_timeout 10;

    # If the client stops reading data, free up the stale client connection after this much time. Default 60.
    send_timeout 2;

Misc Tweaks

Here some addition tweaks that’s improved Nginx performance.

Turn off access logs

Turn off access logs will decrease the delay time and server resources to monitoring and write/read to logs file every request.

    access_log off;

Handle static files directly

Inside each server block serving a PHP web application should appear a location block similar to:

        location ~* \.(js|css|png|jpg|jpeg|gif|ico|wmv|3gp|avi|mpg|mpeg|mp4|flv|mp3|mid|wml|swf|pdf|doc|docx|ppt|pptx|zip)$ {
                expires max;
                log_not_found off;
                add_header Pragma public;
                add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        }

Turn on sendfile

Sendfile copies data between one FD and other from within the kernel. More efficient than read() + write(), since the requires transferring data to and from the user space.

    sendfile on;

Worker Connections

If your ulimit -n output is something like 1024, then your worker connections would need to be set to 1024 or less (maybe even 768), its unlikely that you’ll have 2 x 1024 simultaneous connections especially with something like PHP.

events {
    worker_connections  1024;
}

Additionally you’ve upped the worker_rlimit_nofile to 50000
To be continuous in next week, I’m writing the part 2 of this article about Varnish and Hardening LEMP.

Common issues with Nginx on Arch Linux

There are several issues will occuring with Nginx on Arch Linux, I’ve solved them and give you some tips to blow it out.

Permission problem – Update/Install New Plugins/Themes require FTP access

This is very common error that’s appeared after WordPress installed. It’s very easy to fix, just change ownership of your web folder to http

# chown -R http:http /path/to/web/folder

You can view the result of these optimization tips for Nginx configuration at Arch Việt with 93/100 Google PageSpeed Insight and 80/100 score with 708ms loaded time from Pingdom Tools
Update:

  • 2014.05.29: Add Common issues section

17 thoughts on “Recommended Nginx Configuration for High Traffic WordPress on Small VPS (512 RAM)”

  1. I am using apache and nginx side by side. Nginx handle caching, and apache as web server. I do not have that many pageview, but using blitz.io it could handle (est) 61 Million hit / day. I am using 512 MB of RAM, 3 v Core plan from VPS Provider called Crissic. Great share, btw. I am new follower of your website :-D

  2. Hello,
    What are the locations of the files you change at the bottom of this tutorial?
    Cant seem to find the right files.

    Frank.

    • Yes, I’m rewriting it to make it more cleary and separated some parts of its content to small post of series: Build and Optimize Perfect VPS with lowest hardware (low RAM and CPU) on Digital Ocean.
      I’m finishing it soon ASAP in this month.

  3. Hi there! very nice article,

    I would like to know what should I do to add more wordpress sites into your configuration, it seems than this configuration it’s just for 1 site, but If I seen that you have more on your VPS, and I’m interested about how can I could do that.

    Thanks in advanced
    Best Regards

  4. Hello, I have a vps from digital ocean. I installed vesta cpanel with default configuration. Since today I had the 10$ droplet. But because the cpu was 100% all the time I resized to the 20$ droplet (2 cpu, 2 gb ram). But now both cpu are 100% (not all the time but 70% of time yes). 60% of cpu is used by mysqld. What can you suggest?

    • In my opinion, the cause of high CPU usage is CPanel, it’s not design for low-end hardware server like Digital Ocean’s basic plans. I recommend you using ServerPilot for VPS management. It’s remote service so you don’t pay any server resource for it.
      Or you can using pure nginx + php + mysql like me ^^

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.