littlebizzy / slickstack

Lightning-fast WordPress on Nginx
https://slickstack.io
GNU General Public License v3.0
642 stars 112 forks source link

Microcaching in WooCommerce for real-time stock updates (etc) #158

Closed szrejder closed 1 year ago

szrejder commented 2 years ago

As we talked on Discord - some WooCommerce shops need to be cached in the real time, so that stock changes will be live. Microcaching is a perfect way to achieve this, so that 1-5s for a cache works really well. However, as I checked how to max out the boost while maintaining real time changes, I've encountered multiple things, which would grant an additional boost to microcaching:

fastcgi_cache microcache; (currenty it is set to Wordpress, I'm unsure of the impact of changing that tho) fastcgi_cache_lock on; fastcgi_cache_use_stale updating; fastcgi_cache_background_update on;

https://www.nginx.com/blog/benefits-of-microcaching-nginx/ https://siipo.la/blog/never-miss-the-cache-with-nginx-microcaching These should be a proofs of potential impact.

But, there could be some problem with 404 pages, as stated in update section on second site. It may need to add "any" in fastcgi_cache valid" and "fastcgi_ignore_headers Cache-Control Expires". I'm not sure if it will be easy to implement or would cause much trouble. However, I'm using 3s cache now for my website, It is working, but a lot of time I get EXPIRED instead of HIT.

As they're not needed for a normal, long term caching - it could be implemented as some setting or something.

Best regards

jessuppi commented 2 years ago

Thanks for starting this topic @szrejder

I will respond in more detail, but just saving this (older) example here: https://github.com/kevinohashi/WordPressVPS

jessuppi commented 2 years ago

Also this other topic is related and I might close this one after reviewing in detail:

https://github.com/littlebizzy/slickstack/issues/136

jessuppi commented 2 years ago

I think these topics are sufficiently different, since the other topic is more about non-cached pages like the cart, so I'm going to continue responding here in detail.

Anyway, the name of the FastCGI cache zone doesn't matter at all, we will probably change it to be called SLICKSTACK eventually instead of WORDPRESS to be more generic.

We already have fastcgi_cache_lock on; so it should be the same as what you read there, and we also use the same exact rule for ignoring (WordPress) headers they did fastcgi_ignore_headers Cache-Control Expires Set-Cookie; ...

Ref: https://github.com/littlebizzy/slickstack/blob/master/modules/nginx/nginx-conf.txt

I'm going to review again these directives:

jessuppi commented 2 years ago

A few other interesting links:

Ref: http://forum.centos-webpanel.com/index.php?topic=6255.0 Ref: https://www.appservgrid.com/paw92/index.php/2018/10/24/nginx-caching-for-wordpress-using-fastcgi_cache/

jessuppi commented 2 years ago

Quick side note that I've been playing with these settings in ss-config on some bbPress forum servers, and it seems to be working great so far... no other changes were made to default FastCGI settings.

FCGI_CACHE_VALID="1m"
FCGI_CACHE_INACTIVE="1m"
jessuppi commented 2 years ago

Roots Trellis uses 5-second cache apparently:

https://docs.roots.io/trellis/master/fastcgi-caching/#example-cache-configurations

jessuppi commented 1 year ago

Update: a few weeks ago, we added these directives to SlickStack:

fastcgi_cache_background_update on;
fastcgi_cache_revalidate on;
jessuppi commented 1 year ago

So by default, SlickStack uses fastcgi_cache_valid 200 301 404 1440m ... and the 1440m can be adjusted in ss-config, but the important part is that 200, 301, and 404 responses are cached for several hours by default. By changing these to be cached for only a few seconds, it would degrade performance a lot, and I truly don't know why many devs use such an approach... even if you add WP cache plugins, 301s and 404s are not being cached, unless you are going to maintain multiple cache validity rules in your server blocks based on the HTTP request being received.

In the "update" section on the siipo.la blog article, he mentions using fastcgi_ignore_headers to avoid WordPress causing conflicts in the Nginx cache purging... SlickStack already does this, and yes it's a great idea, for multiple reasons. But I think fastcgi_cache_use_stale is the directive most needing careful consideration, because from my understanding it can either conflict with your other settings, or compliment them.

By default SlickStack uses fastcgi_cache_use_stale error timeout invalid_header updating http_500; and this currently cannot be modified.

Perhaps we could consider opening up that directive to customization in ss-config... but the rule he uses in the blog article fastcgi_cache_use_stale updating; is required for fastcgi_cache_background_update on; so allowing users to modify the stale directive might cause some problems for non-expert Nginx users.

jessuppi commented 1 year ago

I also learned that WordOps caches content for 24 hours by default just like SlickStack... great minds?

They shared this fantastic PHP snippet that can enable microcaching for certain pages:

https://docs.wordops.net/how-to/microcaching-with-nginx/

function add_expires_header( $headers, $wp ) {
    if ( 0 === strpos( $wp->request, 'sample-page' ) ) {
        $headers['X-Accel-Expires'] = '120';
    }
    return $headers;
}
add_filter( 'wp_headers', 'add_expires_header', 10, 2 );
jessuppi commented 1 year ago

TLDR for this long-winded Issue:

By default, SlickStack frowns on microcaching, because it's not very efficient, and because the vast majority of WordPress sites are better served with longer cache expiration rules.

We believe more in community feedback to decide which URLs should have caching disabled in Nginx... for example, by default pages like /cart/ or /checkout/ have Nginx caching disabled in SlickStack. We are slowly expanding support for non-English languages, but this requires feedback and contributions.

That said, if anyone is determined to use microcaching server-wide in SlickStack it should now be better supported now that we support all these directives:

To enable microcaching in SlickStack it should be as easy as changing these lines in ss-config e.g.

FCGI_CACHE_VALID="5s"
FCGI_CACHE_INACTIVE="5s"

Again, this is NOT recommended for the vast majority of cases and users. I'm going to close this for now but further comments are welcome as always.

P.S. @szrejder hopefully with these changes you see less EXPIRED responses and more STALE and UPDATING and ultimately HIT response headers, please post an update if you have the opportunity.

konkhra commented 7 months ago

So what would be a proper configuration for a WooCommerce website with aprox 140k products, pretty high traffic while maintaining real-time stock updates (every 3 min at least)?

Topic started with something like..."Microcaching is a perfect way to achieve this," and ended up with "SlickStack frowns on microcaching, because it's not very efficient". I'm confused if it is a good approach on using micro-caching or not. Please advice accordingly!

jessuppi commented 7 months ago

@konkhra Please see my previous comment for an example configuration:

https://github.com/littlebizzy/slickstack/issues/158#issuecomment-1353585994

You can do this in ss-config

For general questions please join the Discord server as GitHub is for bug reports and feature requests, thank you.