LiteSpeed Cache prevents browsers to re-validate pages

LiteCache

Active Member
#21
For your information. The index.html is identified by the browser as a static file and not dynamic. That's why you can throw your supposed achievement completely overboard.
 

LiteCache

Active Member
#23
For all interested readers of this topic, please do not use the comments of the user @kvv213 as a guide if you plan to use OpenLiteSpeed. 99% of the topics discussed here are based on insufficient knowledge of how to properly configure a server. However, using OLS does not mean additional work in configuration. Most related to Apache. However, you can also complicate things if you only make assumptions and do not acquire enough basic and OLS-independent knowledge.
 
#24
For all interested readers of this topic, please do not use the comments of the user @kvv213 as a guide if you plan to use OpenLiteSpeed. 99% of the topics discussed here are based on insufficient knowledge of how to properly configure a server. However, using OLS does not mean additional work in configuration. Most related to Apache. However, you can also complicate things if you only make assumptions and do not acquire enough basic and OLS-independent knowledge.
I did some more research including reading the manuals from google.

First of all. Let's set the terminology used:
1. LSC - LiteSpeed Cache plugin.
2. LSCP or LSCWP - front face of LSC, that let to configure the LSC from WordPress admin page.


In LiteSpeed httpd server LSC can be controlled over interface or via .htaccess. In OpenLiteSpeed LSC can be controlled via not-documented config section.

BTW here is the config I have in my installation:
Apache config:
module cache {
  internal                1
checkPrivateCache   1
checkPublicCache    1
maxCacheObjSize     1000000
maxStaleAge         200
qsCache             1
reqCookieCache      1
respCookieCache     1
ignoreReqCacheCtrl  1
ignoreRespCacheCtrl 0

enableCache         0
expireInSeconds     3600
enablePrivateCache  0
privateExpireInSeconds 3600
  ls_enabled              1
}
All the settings are default. But I doubt about enableCache and enablePrivateCache.

Then let's move forward. There are two types of cache:

1. The Server side. It is controlled by the settings of LSC or via settings provided by LSCWP. When it is stale it is re-generated by the server. That is simple.
2. The client's browser settings. There is only one possibility for control via header. But here we can have a number of options and not of them are supported by all the browsers especially the old browsers like IE6 that we can forget for a long time and browsers at Mac-devices (this is true only about Safari).

So, I have to rewrite my previous statements to make them more detailed and it belongs to the client's cache at the browser:

1. Expires (that is partially obsolete) defines how long the resource can be considered fresh at the client's side. In OLS this value is transformed into cache-control: max-age. Max-age tells the browser how long it can use its local stored copy of the resource. The other header that do the same job is Last-modified and expires.
2. If I'd like to be sure that a resource (like css or js or html) is updated at the client and not taken from its cache. Then I need to reduce max-age to very small value or even zero or use no-cache or no-store (for proxies) (or no-scache for CDN)). Additional headers like must-revalidate can be used. In all other cases the client's browser will take the resource from its own cache. If I use large max-age then there is no way to urge the client's browser to reload the resource. If this is set to text/html that may arouse additional troubles. For resources it is possible to use versions in their file names like jquery.0.4.5.1.js or add some get request to the URL like main.css?a=b.
3. When max-age is not expired any browser request to resources ends with 200 code. I was not completely true here: if max-age or last-modified or expires tells the browser that the resource is not staled then the browser takes it from its cache. And here the browser shows in its logs Code 200 the same way as it downloaded the resource from the web-server.
4. When max-age/last-modified/expires is expired then browser requests the resource once more from the web-server and if it is not changed (etag helps with that) then it receives 304. The same with soft reload via F5 (hard reload with shift-f5 requests all the resources). With F5 reload the browser tries to reload only vital resources. How the web-server and browser can understand that the resources that is in the browser cache is stil valid? ETag and Last-Modified are help in that. There are not other ways how they can determine that.
5. For dynamic pages LSCWP takes Default expired (or text/html) setting from OLS and the page is not re-requested until this Default is expires. If it is empty then no cache-control is added for public cache. This setting potentially can be changed via adding a personal expire for text/html. When a user is logged into WP then cache-control appears from LSCWP with no-cache directive (it wold be better to see also private here, but with SSL it is not required).

As an example we can take a loot at the web-site that LiteCache promotes:
1675195554144.png

The page was reloaded by F5 (and previously it was opened via going to the same URL but the result is the same). As we can see:

1. text/html page is given with very strict Cache-control that urges the client's browser to check the page every time it has an urge to show it. As we can see there is 304 Code at this page.
1675195576739.png
That (recheck by the browser and resulting 304 code) can be made or via etag hash comparision or via last-modified option. In the request headers we can see both variant responces:
1675195592915.png
Which one was fired - I don't know :)

Also we can notices that this page also has pragma: no-cache html-control for very old browsers.

2. Going lower through the list of the resources. And we can see that all the rest resources doesn't have etag and have maximum max-age. All of them (except two resources with 204 code but they are empty) are returned back with 200 code and they were taken from the browser cache.

3. Imagine that LiteCache teammate would like to change one of the picture at the page. For example, convert the superman into a supergirl. And he just changed the picture and placed it with the same name to the same place. I will not see the updated picture until do the full reload of all the resources for one year since my last visit. And there is only one exception - he will modify the filename or add a request trail to the file.

Let's move forward and take a look at openlitespeed.org site:
1675195608589.png

The page was reloaded (F5) and we can see that the most resources are taken from the browser's cache. The main file text/html doesn't have any cache control. Also it doesn't have etag (and it was downloaded from the server).
The rest of resources have atag and cache-control. So they are downloaded from the browser cache and have code 200 (not 304).

I'll try to configure my OLS in order to get code 304 using the recipe by LiteCache but not at my prod server at firts. And I'll repeat again - there is very little way how to configure LSC in OLS.

>Without exception, etag is only important for dynamic sources, but not for static sources, which is crucial.
I don't agree. Etag is useful for static and dynamic pages. This is one of the way how browser and web-server define the stale browser cache. Easy example https://en.wikipedia.org/wiki/HTTP_ETag and more strict technical explaning https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag
Take into account that static files at web-server can also be changed. Especially if no CMS is used (yes, a web-site can work with just plain HTML files).

>Change the Expire settings as shown above. With the Expires Default setting, you inevitably activate the browser cache for dynamic pages, so that requesting dynamic pages always shows stale content.

Yes, it some cases this can be useful. In other cases it would be better to avoid of storing dynamic pages with exirpes or max-age.
 
#25
OK. I did the test on my test environment with static files that includes one html and one jpg. Because we test the browser behaviour there is no difference how these files were provided by the web-server form dynamic generation or just from the disk.

I was able to modify the following settings of OLS:
1. Enable Expires.
2. Expires Default.
3. Expires By Type.
4. Etag controls - enable or disable.

I can say that the behaviour was the following as I had described before: Code 200 and taking resource from the browser's cache until "max-age" is not expired. F5 urges some resources to be validated and get code 304. Enabling or disabling of etag doesn't play any matter here. Enabling or disabling Enable Expires - the same.

But when I set A0 (that means max-age=0) then I started to get code 304. I can set it via Expires Default or Expires By Type selecting correct MIME-codes for html and jpg. If I have only A0 then if-modified-since triggered:
1675200914258.png
if I use also etag then if-modified-since and if-none-mach are triggered:
1675200961262.png

If I use M0 instead of A0 then the countdown starts not since when the browser got the resources but since their modification time at the server. While it is M0 it acts the same as A0.

If I increase A0 or M0 for reasonable values like 600 (10 minutes) then I receive code 200 until max-age is expired. But M600 counts from the file modification at the server side so for old files it will expires earlier and for all the clients.

If I set A1000 and modify a file. The browser will not reload the resource from the web-server until this 1000 of seconds ends. ETag doesn't help here. We receive code 200 from with load from the broswer's cache. It doesn't do any validation. But after that, when 1000 of seconds passed, the browser redownload the resource.

So, the behaviour is obvious and not in contra force with my previous states. I mean - now it is clear how to achieve code 304 with OLS. Not only for text/html but also for other types of files.
 
Last edited:
#26
Regarding to the speed of the getting of the resources (so with 304 code we can use all the types of resources from web-server) my measurements are not very correct because the web-server is installed in Hyper-V container that is hosted at the same computer I'm sitting but we can notice a slightly reduction of the timing with 304 code:
html - downloading 200 14 ms, 304 13 ms (first time 304 23), 200 disk cache 15 ms
jpg - downloading 200 5 ms, 304 6 ms (first time 304 8), 200 memory cache 0 ms

So, here we can see, that the validation took longer for the first time than any other types of receiving. That can be just a fluctuation at browser or server sides. But anyway - taking a resource from a local cache is faster in all cases.
 

LiteCache

Active Member
#29
....but we can notice a slightly reduction of the timing with 304 code:
html - downloading 200 14 ms, 304 13 ms (first time 304 23), 200 disk cache 15 ms
jpg - downloading 200 5 ms, 304 6 ms (first time 304 8), 200 memory cache 0 ms
Of course, there must be an reduction, but it is only caused by browser cache behavior and has nothing to do with LiteSpeed and LScache. As already said, index.html at your page is identified as a static source and is not cached by LScache.
 

LiteCache

Active Member
#32
Thank you!

I've got dzen with this already. Code 304 will work freely.
And again and again, if you get 304 status code in your case and only in your case this is not a result of special settings. This is a absolute normal behaviour of every browser if he requests a static source that is not css, js or image. In your case index.html is a static source!
 
#33
I followed this conversation from the beginning, it was a very interesting conversation.

Since I'm a newbie, and don't really understand the complicated technical issues that you guys are talking about.

I also had the same problem, and this happened after I integrated my site with Ezoic. Some of the problems I faced.

Warning that appears on my wordpress dashboard

Litespeed Cache and Ezoic Trouble kumiskiri.com.png

The warning that popped up on the ezoic dashboard after I did the cache debug test.

Litespeed Cache and Ezoic Trouble kumiskiri.png

I made some changes to the menu structure and update articles every day. The problem that arises is that my menu changes and updated articles are not displayed at all after I get the warnings in no 1 and 2.

I appreciate any help in this matter. Please take a peek at my site kumiskiri.com to confirm this issue.

Structur related issue:

The problem is related to the custom structure in the category Panduan: . Like the picture.

1.png

But after I visit my site with incognito. field facts, it is much different, the display still shows the old structure. as shown:

2.png

Another problem is related to article updates:

I posted the article https://kumiskiri.com/script-auto-post/ on 2023/08/30 at 7:41 pm.

However, when I visit the site with incognito, the article I posted is not displayed on the web page, but the site url is active and can be visited.

So, my question is please help me and what action should I take to solve this problem.
 

Cold-Egg

Administrator
#34
Multiple cache systems may cause such an issue. In your case, it seems you have Ezoic CDN cache enabled, please use either Ezoic cache, or LSCache.
 
#35
Multiple cache systems may cause such an issue. In your case, it seems you have Ezoic CDN cache enabled, please use either Ezoic cache, or LSCache.
I tried disabling the ezoic cache and the problem was solved.

But, is there any way to combine litespeed cache and ezoic so that they don't clash?
 

LiteCache

Active Member
#36
But, is there any way to combine litespeed cache and ezoic so that they don't clash?
No, this is not possible because Ezoic would have to know LiteSpeed's cache status in order to forward the request to your server in case of doubt. Otherwise, Ezoic would always deliver outdated content and would never query your server for changed content. Apart from that and in the case that you use Wordpress, an upstream CDN cache is incompatible with the LiteSpeed Cache Vary, which are responsible, for example, for allowing you to use Guestmode, webp Replacement or Cache Mobile. Ezoic would always deliver the wrong cache.
 
#37
No, this is not possible because Ezoic would have to know LiteSpeed's cache status in order to forward the request to your server in case of doubt. Otherwise, Ezoic would always deliver outdated content and would never query your server for changed content. Apart from that and in the case that you use Wordpress, an upstream CDN cache is incompatible with the LiteSpeed Cache Vary, which are responsible, for example, for allowing you to use Guestmode, webp Replacement or Cache Mobile. Ezoic would always deliver the wrong cache.
I did a new configuration between litespeed cache + Ezoic.

I didn't change the cache configuration for litepseed, but I added a new module paramater in the openlitespeed virtual host:

storagePath /dev/shm/$vh_name

When I applied this configuration, it worked fine so far with the main cache being taken over by ezoic.

Test results after I did the new configuration

Although there is no significant change, the new configuration that I implemented has a slight change specifically for mobile.

For Mobile:

1.png

Mobile performance increased by 3%. Lol..hahahha...but Accessibility decreased

For Desktop:

2.png

Performance decreased dramatically by 6%, but accessibility increased.


So the question: I'm wondering if the configuration I applied has the effect of being a time bomb or is it technically correct? Please give me some advice.
 
Last edited:
Top