• If you are still using CentOS 7.9, it's time to convert to Alma 8 with the free centos2alma tool by Plesk or Plesk Migrator. Please let us know your experiences or concerns in this thread:
    CentOS2Alma discussion

Question Optimal nginx performance Wordpress

BobClaas

Basic Pleskian
I'm looking for the best nginx performance with Wordpress and WP Super Cache module. Found a lot of threads en websites with only seperated snippets of code. Since a lot of people are looking for performance, my hope is that we can build the optimal directives for Nginx
I'm no expert. It's a collection of snippets. This is where i am so far. There is an error in de code somewhere, it breaks the site.
Last working code was scoring 93 out of 100 with google speed and 192 ms on AB (normal website):

nginx Settings
OFF Nginx as a reverse proxy
ON - Smart static files processing
ON - Serve static files directly by nginx

nginx Directives
Code:
### gzip compression ###
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/plain text/javascript application/javascript application/x-javascript text/xml text/css;
gzip_vary on;
gzip_proxied any;
# end gzip configuration

### Nginx CACHING ###
location ~* \.(?:ico|css|js|gif|jpe?g|png|svg|woff)$ {
    expires 30d;
    add_header Cache-Control "public"; log_not_found off;
}

location ~* \.(jpg|jpeg|gif|png)$ {
    expires 365d;log_not_found off;
}

location ~* \.(pdf|css|html|js|swf)$ {
    expires 2d;log_not_found off;
}

location ~ \.css {
    add_header  Content-Type    text/css;
}
location ~ \.js {
    add_header  Content-Type    application/x-javascript;
}

### WP Super Cache Below ###
set $cache_uri $request_uri;

# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
    set $cache_uri 'null cache';
}
if ($query_string != "") {
    set $cache_uri 'null cache';
}

# Don't cache uris containing the following segments
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 $cache_uri 'null cache';
}

# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in") {
    set $cache_uri 'null cache';
}

# Use cached or actual file if they exists, otherwise pass request to WordPress
location ~ / {
   try_files /wp-content/cache/supercache/$http_host/$cache_uri/index.html $uri $uri/ /index.php ;
}
### ADMIN ###
rewrite ^/wp-admin/$ /wp-admin/index.php last;

### NON ADMIN ###
if (!-e $request_filename){
    #rewrite ^(.*)$ /index.php?$1; break;
    rewrite ^/(.*)$ /index.php?q=$1 last;
}

p.s. Seems u have to restart nginx to let it take effect.

Code:
]# ab -n 100 -c 5 https://nextairdrop.com/
Server Software:        nginx
Server Hostname:        nextairdrop.com
Server Port:            443
SSL/TLS Protocol:       TLSv1/SSLv3,ECDHE-RSA-AES256-GCM-SHA384,2048,256
***
Requests per second:    24.66 [#/sec] (mean)
Time per request:       202.787 [ms] (mean)
Time per request:       40.557 [ms] (mean, across all concurrent requests)
Transfer rate:          1284.92 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        5    7   3.2      6      20
Processing:   127  187  32.3    183     272
Waiting:      126  187  32.3    183     271
Total:        133  195  32.7    192     287

Percentage of the requests served within a certain time (ms)
  50%    192
  66%    203
  75%    215
  80%    223
  90%    240
  95%    262
  98%    277
  99%    287
 100%    287 (longest request)
 
Don't forget this one if you are switching to only using nginx (excluding Apache) and use permalinks in Wordpress. This will avoid some 404 errors.
Code:
# Wordpress Permalinks
if (!-e $request_filename) {
    rewrite ^(.+)$ /index.php?q=$1 last;
}


You may also want to consider the following for security:
Code:
# Security
location ~* wp-config.php { deny all; }
location ~* "^/wp-content/(?!plugins/).*\.php" { deny all; }


And here is the full script I recommend running:
Code:
# WORDPRESS PERMALINKS
if (!-e $request_filename) {
    rewrite ^(.+)$ /index.php?q=$1 last;
}

# GZIP Compression
gzip on;
gzip_disable "MSIE [1-6]\\.(?!.*SV1)";
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_proxied any;
gzip_comp_level 9;
gzip_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon image/bmp image/svg+xml;
gzip_vary on;

# NGINX Caching
location ~* \.(?:ico|css|js|gif|jpe?g|png|svg|woff)$ {
    expires 30d;
    add_header Cache-Control "public";
    log_not_found off;
}

location ~* \.(jpg|jpeg|gif|png)$ {
    expires 365d;
    log_not_found off;
}

location ~* \.(pdf|css|html|js|swf)$ {
    expires 2d;
    log_not_found off;
}

location ~ \.css {
    add_header  Content-Type    text/css;
}
location ~ \.js {
    add_header  Content-Type    application/x-javascript;
}

# SECURITY
location ~* wp-config.php { deny all; }
location ~* "^/wp-content/(?!plugins/).*\.php" { deny all; }


Not sure if Plesk does this automatically, but I always go in and restart nginx.

1. Login to ssh
2. command to run: service nginx restart
3. Recommend clearing browser cache and refreshing page.

*Please take the above with a grain of salt, I'm fairly new to Plesk and am still a novice when it comes to nginx and Apache. I can confirm that the above settings work with Plesk Version 17.8.11 Update #17 and Wordpress Version 4.9.8.

Best,
Ben
 
Last edited:
Back
Top