• We value your experience with Plesk during 2024
    Plesk strives to perform even better in 2025. To help us improve further, please answer a few questions about your experience with Plesk Obsidian 2024.
    Please take this short survey:

    https://pt-research.typeform.com/to/AmZvSXkx
  • The Horde webmail has been deprecated. Its complete removal is scheduled for April 2025. For details and recommended actions, see the Feature and Deprecation Plan.
  • We’re working on enhancing the Monitoring feature in Plesk, and we could really use your expertise! If you’re open to sharing your experiences with server and website monitoring or providing feedback, we’d love to have a one-hour online meeting with you.

Question Nginx microcache configuration for high traffic sites

It's not just one site but multiple websites.
In terms of resource usage, what's better: Apache + Nginx or Apache + Nginx with microcache?
 
When we are talking about nginx microcache it is not necessary to put a big time like 10min. Only 15s for example already produces significant results. This is because when nginx needs to update the cache it requests from the machine itself (localhost connection) if it is properly configured.
For example, let's say that in one minute there are 10,000 requests on the server. In practice, with nginx microcache there are only 4 requests. This is because Nginx generates the cache only once and then delivers the cached page for the next requests. Even a value like 1s would have great effect. I really believe Plesk should put this as a default setting. It simply does not make sense. I think this setting will help to decrease the use of resources, when in practice it does not help at all.


I think that putting this as a default setting, it would be very dangerous.

What happens if someone installs a shopping cart?

Correct me if I'm wrong :)


Secondly, if I understood virtubox correctly, this mechanism only works in the moment when apache can not answer?

For example, when one page on the blog becomes viral and gets a lot of traffic from social media. Then this feature will help to handle this traffic?

Correct me if I'm wrong :)


What happens if I have an WP Super Cache or other caching plugin installed? In this case, using this feature will also be helpful?
 
Last edited:
Do you know why here is displaying "BYPASS"?
View attachment 14176
These are my nginx microcache settings.
View attachment 14175
It shouldn't bypass proxy with these caching settings. Need more info. Could you please provide more info, for example your vhost Nginx config (in PM)?

The main purpose of microcaching is to reduce downtime by serving cache each time the next upstream is down. So in case of high-traffic, if Apache timeout or isn't able to answer to a request, Nginx will use micro-caching instead of displaying a 502 Bad Gateway.
During Let's Encrypt renewal, it will also avoid this error.
You're wrong. The main purpose of caching is always to reduce system load and increase responsibility by using upstream (and PHP) only once per defined period of time. Managing backend inaccessibility periods with stale cache records is just a good bonus.

Plesk micro-caching configuration use the directive proxy_cache_use_stale which allow nginx to server content from cache only for the following upstream status
Wrong again. proxy_cache_use_stale directive allows returning stale cache records (records with expired TTL) if upstream is inacsessible. When upstream is accessible, record is fetched from upstrean, then being returned from cache during TTL, then fetched from upstream again.
 
It shouldn't bypass proxy with these caching settings. Need more info. Could you please provide more info, for example your vhost Nginx config (in PM)?

I have tried with the same settings and cache status is always BYPASS
Code:
content-encoding: br
content-type: text/html; charset=UTF-8
date: Wed, 21 Mar 2018 10:18:41 GMT
link: <https://XXX.xyz/index.php/wp-json/>; rel="https://api.w.org/", <https://XXX.xyz/>; rel=shortlink
ms-author-via: DAV
referrer-policy: strict-origin-when-cross-origin
server: nginx
status: 200
strict-transport-security: max-age=15799999;
vary: Accept-Encoding
x-cache-status: BYPASS
x-content-type-options: nosniff
x-frame-options: sameorigin
x-powered-by: PleskLin
x-robots-tag: noindex
x-xss-protection: 1; mode=block

By checking my vhost, I have noticed the variable $no_cache isn't set to 0 initially :
Code:
set $no_cache "";

        if ($request_uri ~* "/wp-admin/") {
                set $no_cache 1;
        }


You're wrong. The main purpose of caching is always to reduce system load and increase responsibility by using upstream (and PHP) only once per defined period of time. Managing backend inaccessibility periods with stale cache records is just a good bonus.
Sorry, I was thinking it was mostly used to avoid 502 bad gateway due to Apache. But in this case, it may require to customize nginx configuration for each website to avoid issues with cache. I'm not sure it's the easiest cache solution for Plesk users. Or it will be great to be able to set a list of cookies to bypass the cache, instead of cookies to cache.

Wrong again. proxy_cache_use_stale directive allows returning stale cache records (records with expired TTL) if upstream is inacsessible. When upstream is accessible, record is fetched from upstrean, then being returned from cache during TTL, then fetched from upstream again.

Yes, after reading nginx doc again, you are right. I'm french, so the word "stale" wasn't explicit for me, but it make sense now.
 
I have tried with the same settings and cache status is always BYPASS
Code:
content-encoding: br
content-type: text/html; charset=UTF-8
date: Wed, 21 Mar 2018 10:18:41 GMT
link: <https://XXX.xyz/index.php/wp-json/>; rel="https://api.w.org/", <https://XXX.xyz/>; rel=shortlink
ms-author-via: DAV
referrer-policy: strict-origin-when-cross-origin
server: nginx
status: 200
strict-transport-security: max-age=15799999;
vary: Accept-Encoding
x-cache-status: BYPASS
x-content-type-options: nosniff
x-frame-options: sameorigin
x-powered-by: PleskLin
x-robots-tag: noindex
x-xss-protection: 1; mode=block
I see response headers only. Could you please provide request headers for this bypassed request?
 
I see response headers only. Could you please provide request headers for this bypassed request?

Yes :
Code:
:authority: XXX.xyz
:method: GET
:path: /
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
accept-encoding: gzip, deflate, br
accept-language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
cache-control: max-age=0
cookie: g5-collapsed={"particles.search.":false}; wordpress_test_cookie=WP+Cookie+check
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.45 Safari/537.36
XXX.xyz    jquery.js?ver=1.12.4    autoptimize_5180077a0836686a332724c2abec7a4d.js    wp-emoji-release.min.js?ver=4.9.4    favicon.ico
 
Code:
cookie: g5-collapsed={"particles.search.":false}; wordpress_test_cookie=WP+Cookie+check
Plesk Nginx caching doesn't allow serving requests with cookies from cache by default, because cookies suggests interaction with server backend. However, you may add a list of "safe" cookie names to appropriate field if you're absolutely sure using someone's cached answer for request with these cookies is safe for your users.
 
Last edited:
Problem is 99% of sites use cookies. Therefore this Nginx caching is not going to work with most sites. Surely a switch to cache all that activates "proxy_ignore_headers" and then a field to add cookies not to ignore would be more useful? Most cookies can be cached. Just some cookies like those used on shopping carts should be excluded maybe?
 
Problem is 99% of sites use cookies. Therefore this Nginx caching is not going to work with most sites. Surely a switch to cache all that activates "proxy_ignore_headers" and then a field to add cookies not to ignore would be more useful? Most cookies can be cached. Just some cookies like those used on shopping carts should be excluded maybe?

I agree with you Laurence@ , it's really painful to list all "safe cookies" to allow Nginx cache.

I'm using Nginx proxy-cache with the blogging app Ghost and it cache everything with the directive "proxy_ignore_headers Set-Cookie;" expected the location /ghost (the same than /wp-admin on wordpress).
Here an example :

Code:
    add_header X-Proxy-Cache $upstream_cache_status;
       
    location / {
        proxy_cache ghost;
        proxy_cache_valid 200 30;
        proxy_cache_valid 404 1m;
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
        proxy_ignore_headers Set-Cookie;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;
    }

   
    location /content/images {
        alias /var/www/ghost.fr/htdocs/content/images;
        try_files $uri$webp_suffix $uri =404;
        access_log off;
        expires max;
    }




    location ~ ^/(?:ghost|signout) { 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;
        add_header Cache-Control "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0";
        pagespeed standby;
    }

It should be possible to do something similar with WordPress, like :

Code:
    set $no_cache "";
    set $bypass_reason "";
   
   
   
    # do not cache wordpress location
    location ~ ^/(?:wp-admin|xmlrpc.php|wp-(login|register|mail).php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml) { 
       include proxy_params;
       proxy_pass https://wordpress;
       add_header Cache-Control "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0";
       set $bypass_reason "location";
    }
       
    # Bypass if it's a POST request
    if ($request_method = POST) {
    set $no_cache 1;
    set $bypass_reason "POST request";
    }
   
    if ($http_cookie ~* "(wordpress_logged_in_|wp\-postpass_|woocommerce_items_in_cart|woocommerce_cart_hash|wptouch_switch_toogle|comment_author_|comment_author_email_)") {
    set $no_cache 1;
    set $bypass_reason "HTTP Cookie";
    }
 
Where would you put that code? Little confused there.

But going back to the overall function, I don't understand why Plesk would add a cache that simply won't work on 99% of websites. Is it just marketing? "Hey we do microcaching (you just can't use it without a degree in computer science).
 
Oh yes. It would be brilliant if it would work as easily as the popular Wordpress cache plugins
 
Back
Top