Skip to main content

How to get the best performance from your NGINX Web Server

Category

At Zodiac Media we are big fans of NGINX and Apache2. Personally I swing more towards NGINX, as the configuration is super simple and very transparent. Like all web servers, it needs to be tuned to get the best possible performance out of it. NGINX was designed to deal with the C10k problem, this refers to the optimization connections so that they can handle client connections in the range of ten thousand (and over) simultaneously.

This can be fairly complicated if you are not used to using the command line. If this is not the case, then get in touch, this is our bread and butter. These configuration settings should allow you to get every bit of performance out of your NGINX setup.

Connection Settings

First things first, we are going to want to find out what are system can handle.

ulimit -n

This will give us a number of worker connections that our core can handle.

We then want to go ahead and edit /etc/nginx/nginx.conf. The events block of the file should look like this.

events {
    use epoll;
    worker_connections 123456;
    multi_accept on;
}

You want to change the 123456 number of worker connections to the number you got from running ulimit. To explain what the other parts do, multi_accept allows for a worker to accept new connections at a time. use epoll means that disk I/O will be utilised to the best of it’s ability.

HTTP and TCP settings

keepalive_timeout 65;
keepalive_requests 100000;
sendfile on;
tcp_nopush on;
tcp_nodelay on;

The first two settings control the keepalive timeout and request durations. Sendfile helps with optimising serving of static files such as banner images. tcp_nopush allows TCP to send multiple buffers as individual packets. tcp_nopush optimises the amount of data sent over the connection at one time.

Client Timeouts

client_header_timeout  3m;
client_body_timeout    3m;
send_timeout           3m;

client_body_timeout  and client_header_timeout are the amount of time our server will wait for the page body and header to be sent. send_timeout is the amount of time nginx will wait to close a connection.

Asset Caching

Add this to your server configuration, this is stored inside the  /etc/nginx/sites-available/ folder

location ~* .(woff|eot|ttf|svg|mp4|webm|jpg|jpeg|png|gif|ico|css|js)$ {
    expires 365d;
	access_log off;
	log_not_found     off;
}

This means that all of your static assets will be cached by the client for 365 days and also when serving those assets the client access will not be logged. I prefer not to log access to site assets, I don’t see the point in creating log bloat.

Next add the following to your /etc/nginx/nginx.conf. file,

open_file_cache          max=2500 inactive=15;
open_file_cache_valid    60s;
open_file_cache_min_uses 5;
open_file_cache_errors   off;

open_file_cache tells the serve to cache 2500 open file handles for 15 seconds.  open_file_cache_valid  is the amount of time that the handles will be considered valid. open_file_cache_min_uses denotes the mimic number of times that the file has to be accessed before it is classed as suitable for caching. open_file_cache_errors disables errors. 

Gzipping Our Content

gzip on;
gzip_vary on;
gzip_min_length 50;
gzip_comp_level 9;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_proxied expired no-cache no-store private auth;
gzip_types: text/html application/x-javascript text/css application/javascript text/javascript text/plain text/xml application/json application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/xml font/eot font/opentype font/otf image/svg+xml image/vnd.microsoft.icon;
gzip_disable "MSIE [1-6]\.”;

Gzipping our content means that we can serve our content compressed to our clients. This will shave time off every request for the listed filetypes.

Enable HTTP/2

HTTP/2 is the new version of HTTP. The main advantage of HTTP/2 is its allows for a much higher transfer speed for websites that our full of content. It allows all assets to be downloaded in parallel rather than in a queue like HTTP/1. It also compresses all HTTP headers and transfers pages as binary and not as tex. To use HTTP/2 you will need to have a SSL certificate installed, we recommend letsencrypt.org

You are going to firstly want to update your system packages,

sudo apt-get update

And then install NGINX,

sudo apt-get install nginx

Next thing will be to edit your server configuration, this is stored inside the  /etc/nginx/sites-available/ folder

You should currently have a line that looks like this,

listen 443 ssl default_server;

Change it to this,

listen 443 ssl http2 default_server;

Save the file and then from the command line reload NGINX

sudo service nginx reload

Congratulations, you now have HTTP/2 enabled and a bullet proof NGINX setup.