Skip to main content

Nginx optimization for best Performance and Security

Lovekesh Kumar
Written by Lovekesh Kumar
Article on 6 min read

Get started with DigitalOcean and host your projects for free. Get $100 credits now!

Nginx is a popular web server that can also be used as a reverse proxy, load balancer, mail proxy, and HTTP cache.

Created in 2004 by Igor Sysoev to handle large amounts of concurrent connections, Nginx is a popular web server used to host some of the largest and most high-traffic sites on the internet.

We can easily host static and dynamic websites using Nginx by easily configuring them according to our needs. Nginx comes with different in-built modules which help us in achieving the results that we want during setting up a website.

When your hosted website gets opened to the world than two factors are very important to any developer and those factors are performance and security.

In this tutorial, we will be configuring Nginx for the best performance and security.

Configure Nginx for best performance

1. Compression

Compression is something that compresses your assets that are being served from the server. Compression is the direct factor affecting your website performance.

  • Enable gzip or brotli only for relevant content, such as text, JavaScript, and CSS files.
  • Do not increase the compression level, as this costs CPU effort without a commensurate increase in throughput.
  • Evaluate the effect of enabling compression by enabling and disabling gzip for different types and sizes of content.
  • Add brotli support on your Nginx server.
Brotli isn't a standard NGINX module, check the Google ngx_brotli project for how to build NGINX with Brotli!

2. Connection Handling

Connection handling stands for handle the connections that are requested to your server.
There are many ways in which we can optimize this step. Below are given some:-

  • multi_accept off - A worker process accepts one new connection at a time (the default). If enabled, a worker process accepts all new connections at once.
We recommend keeping the default value (off), unless you’re sure there’s a benefit to changing it. Start performance testing with the default value to better measure predictable scale.
  • accept_mutex off - All worker processes are notified about new connections. If enabled, worker processes accept new connections by turns.
We recommend keeping the default value (off) unless you have extensive knowledge of your app’s performance and the opportunity to test under a variety of conditions, but it can lead to inefficient use of system resources if the volume of new connections is low. Changing the value to on might be beneficial under some high loads.
  • listen80 reuseport - Enables port sharding, which means an individual listening socket is created for each worker process (using the SO_REUSEPORT socket option), which allows the kernel to distribute incoming connections among worker processes.
Sharding is a method for distributing data across multiple machines.

3. Logging

Logging is an important tool for managing and auditing your system. Logging large amounts of data, and storing large logs, can strain system resources, but we recommend that you disable logging only in very specific cases or for performance troubleshooting.

  • access_logoff – Disables access logging.
  • access_log/path/to/access.logmainbuffer=16k – Enables buffering to access logs.

4. SSL

When SSL performance is paramount, it’s always a good idea to try different key sizes and types in your environment, finding the correct balance for your specific security needs between longer keys for increased security and shorter keys for faster performance. An easy test is to move from more traditional RSA keys to Elliptical Curve Cryptography (ECC), which uses smaller key sizes and is therefore computationally faster for the same level of security.

To generate quick, self‑signed ECC P‑256 keys for testing, run these commands:

 openssl ecparam -out ./nginx-ecc-p256.key -name prime256v1 -genkey
 openssl req -new -key ./nginx-ecc-p256.key -out ./nginx-ecc-p256-csr.pem -subj '/CN=localhost'
 openssl req -x509 -nodes -days 30 -key ./nginx-ecc-p256.key -in ./nginx-ecc-p256-csr.pem -out ./nginx-ecc-p256.pem

Configure Nginx for best security

1. Use SSL certificate

SSL is the basic layer of security that uses a secure socket layer to encrypt your connection to the web server.
For websites like e-commerce or banking encryption of data between client and server is very important. It prevents hackers from stealing your sensitive data.

You can use OpenSSL or Let's Encrypt to generate free SSL certificates for your websites.

Read more about installing SSL with Let's Encrypt and Nginx on Ubuntu.

2. Disable unwanted HTTP methods

There are HTTP methods like GET, HEAD, POST, TRACE, DELETE, PUT, OPTIONS enabled on a web server. We recommend you disable the HTTP methods which are not in use on the webserver.

Enabled methods like TRACE or DELETE are risky as it can allow Cross-Site Tracking attacks and potentially allow a hacker to steal the cookie information.

By adding the following code block in your Nginx configuration file you can filter out methods such as TRACE and DELETE.

location / {
limit_except GET HEAD POST { deny all; }

You can also add conditions with an error code if any request made with disabled HTTP methods like:

if ($request_method !~ ^(GET|HEAD|POST)$ ) 
return 405; 

3. Disable unused modules from Nginx

When you install Nginx on your machine then it comes with different modules that add various types of functionality to your web server. Since there is no place for anything without use so you should disable the modules that are not in use.

By doing so, you can minimize the risk of potential vulnerability by limiting the operations usage.

To do this, use the configure option during installation. In the example below, we disable the autoindex module, which generates automatic directory listings, and then recompile Nginx.

# ./configure --without-http_autoindex_module
# make
# make install

From here, we will discuss the HTTP security headers

Below given HTTP security headers should be in your site config file. We recommend you include them in your Nginx site config file.

# security headers
add_header X-Frame-Options           "SAMEORIGIN" always;
add_header X-XSS-Protection          "1; mode=block" always;
add_header X-Content-Type-Options    "nosniff" always;
add_header Referrer-Policy           "no-referrer-when-downgrade" always;
add_header Content-Security-Policy   "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Include these headers in /etc/nginx/sites-available/ file

4. X-Frame-Options

The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a <frame>, <iframe>, <embed> or <object>.

This header prevents clickjacking attacks by ensuring that the malicious content is not being embedded into the website.

5. X-XSS-Protection

The X-XSS-Protection header is used to filter out cross-site scripting (XSS) in modern browsers.

This is usually enabled by default, but using it will enforce it. It is supported by Internet Explorer 8+, Chrome, and Safari.

6. X-Content-Type-Options

The X-Content-Type-Options header prevents Internet Explorer and Google Chrome from sniffing a response away from the declared Content-Type. This helps reduce the danger of drive-by downloads and helps treat the content the right way.

7. Referrer Policy

The Referrer-Policy HTTP header controls how much referrer information (sent via the Referer header) should be included with requests.

Aside from the HTTP header, you can set this policy in HTML.

Send the origin, path, and query string in Referer when the protocol security level stays the same or improves (HTTP→HTTP, HTTP→HTTPS, HTTPS→HTTPS). Don't send the Referer header for requests to less secure destinations (HTTPS→HTTP, HTTPS→file).

8. Content Security Policy

The Content-Security-Policy is an HTTP security header that provides an additional layer of security.

This policy allows the browser to only loads the approved resources. Doing so helps in preventing the attacks like Cross-Site Scripting (XSS) and other code injection attacks

9. HTTP Strict Transport Security (HSTS)

The Strict-Transport-Security header is a security enhancement that restricts web browsers to access web servers solely over HTTPS. This ensures the connection cannot be established through an insecure HTTP connection which could be susceptible to attacks.

The protection only applies after a user has visited the site at least once, relying on the principle of Trust on first use.

Some HTTP Header Checker Tools

You can also use the Chrome Dev Tools to see the header response.

  1. Open the chrome dev tools and choose the network pane.
  2. Reload the website and click find your website under Name list.
  3. Click on the website and you will see all the response headers in the right side window.
See all the response headers in the Chrome Dev Tools

Best performance and security configuration file for Nginx

You can generate the best performance and security configuration for your Nginx server using this awesome tool by DigitalOcean.

NGINXConfig - The easiest way to configure a performant, secure, and stable nginx server.


In this tutorial, we learn about optimizing the Nginx for best performance and security by following the best security practices and performance tuning for the Nginx.

If you have further questions or need any help then Create New Topic in Codebulbs Forum.


Something Missing?

If something is missing in this post or if you found some part confusing, then you can:

We love hearing from you!

Give Feedback

Thank you for the feedback! (Join Codebulbs Writers Club)

Sorry to hear that. Please tell us how we can improve. (Suggest an Improvement)

Codebulbs Writers Club

If you are passionate about web, open-source, or javascript and want to share, join Codebulbs writers club!

Join Program