WIP: reverse_proxy,endpoint,uploaded_media: add immutable cache-control flag #1068

Closed
Yonle wants to merge 7 commits from Yonle/akkoma:cachecontrol-1 into develop
Contributor
No description provided.
reverse_proxy,endpoint,uploaded_media: add immutable cache-control flag
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
985d78204c
floatingghost left a comment
Owner

this makes sense I think

Will leave it for a bit in case anyone can think of any weird edge cases

this makes sense I think Will leave it for a bit in case anyone can think of any weird edge cases
Author
Contributor

@floatingghost wrote in #1068 (comment):

this makes sense I think

Will leave it for a bit in case anyone can think of any weird edge cases

unless they have weird endpoint that changes pictures on different requests, it seems it's rather onto them. but most of the time, static datas are basically returning the same bytes (emojis, avatar, medias, etc). so refetching them constantly doesn't make any sense.

for the concern though, scripts will need some kind of versioning on their endpoint (eg, app.8b403.js), but i think we're safe with this one as most apps nowadays are built with this one.

the only thing that need to keep in watch will be probably /static/terms-of-service.html and /instance/panel.html, as these can be changed from the time to time. we can fix this by making these two endpoints to have cache expirations of 24h or 12h. eh, we're good:

[yonle@yonle hidamari_sketch]$ curl -sI https://fedinet.waltuh.cyou/static/terms-of-service.html | grep -i Cache-Control
cache-control: public, no-cache
[yonle@yonle hidamari_sketch]$ curl -sI https://fedinet.waltuh.cyou/instance/panel.html | grep -i Cache-Control
cache-control: public, no-cache
[yonle@yonle hidamari_sketch]$ curl -sI https://fedinet.waltuh.cyou/robots.txt | grep -i Cache-Control
cache-control: public, no-cache
@floatingghost wrote in https://akkoma.dev/AkkomaGang/akkoma/pulls/1068#issuecomment-16059: > this makes sense I think > > Will leave it for a bit in case anyone can think of any weird edge cases unless they have weird endpoint that changes pictures on different requests, it seems it's rather onto them. but most of the time, static datas are basically returning the same bytes (emojis, avatar, medias, etc). so refetching them constantly doesn't make any sense. for the concern though, scripts will need some kind of versioning on their endpoint (eg, `app.8b403.js`), but i think we're safe with this one as most apps nowadays are built with this one. ~~the only thing that need to keep in watch will be probably `/static/terms-of-service.html` and `/instance/panel.html`, as these can be changed from the time to time. we can fix this by making these two endpoints to have cache expirations of 24h or 12h.~~ eh, we're good: ``` [yonle@yonle hidamari_sketch]$ curl -sI https://fedinet.waltuh.cyou/static/terms-of-service.html | grep -i Cache-Control cache-control: public, no-cache [yonle@yonle hidamari_sketch]$ curl -sI https://fedinet.waltuh.cyou/instance/panel.html | grep -i Cache-Control cache-control: public, no-cache [yonle@yonle hidamari_sketch]$ curl -sI https://fedinet.waltuh.cyou/robots.txt | grep -i Cache-Control cache-control: public, no-cache ```
Owner

For uploaded local media, immutable is definitely fine, especially since "dedupe" is enforced and the filepaths thus contain the hash of the content. For reverse proxied content it should be fine too; maybe not perfectly accurate but fine (I’m also hoping the reverse proxy uses any remote Cache-Control info when available, but haven’t checked)

But for local emoji and frontend images, claiming there won’t be changes for at least two weeks seems problematic. Admins may reasonably just overwrite the configured file to switch out the default background for example and emoji images are updated too sometimes (if the pack was revised or to recompress inefficient images). I don’t think we can claim immutability here, at least not for such a long time.

For uploaded local media, `immutable` is definitely fine, especially since "dedupe" is enforced and the filepaths thus contain the hash of the content. For reverse proxied content it should be fine too; maybe not perfectly accurate but fine *(I’m also hoping the reverse proxy uses any remote `Cache-Control` info when available, but haven’t checked)* But for local emoji and frontend images, claiming there won’t be changes for at least two weeks seems problematic. Admins may reasonably just overwrite the configured file to switch out the default background for example and emoji images are updated too sometimes (if the pack was revised or to recompress inefficient images). I don’t think we can claim immutability here, at least not for such a long time.
Author
Contributor

@Oneric wrote in #1068 (comment):

But for local emoji and frontend images, claiming there won’t be changes for at least two weeks seems problematic. Admins may reasonably just overwrite the configured file to switch out the default background for example

if for instance the admin changes the default background, the URL endpoint to that new background will be updated & shouldn't cause issue. It will only be problematic when the endpoint used for the background is the same exact endpoint, for example, https://example.com/background.jpg

and emoji images are updated too sometimes (if the pack was revised or to recompress inefficient images). I don’t think we can claim immutability here, at least not for such a long time.

the problem here is that 10-30 emojis images are kept being refetched on every textbox interactions, either via the new post or reply field of a post. Emojis images under the same :name: are a bit rare to get updated (unless they're overriding those with the same name, which may require their users to clear cache, however 2w cache should makes sense here), however a pack change should affect literally nothing as the endpoint for emoji pack list are never cached by default.

@Oneric wrote in https://akkoma.dev/AkkomaGang/akkoma/pulls/1068#issuecomment-16062: > But for local emoji and frontend images, claiming there won’t be changes for at least two weeks seems problematic. Admins may reasonably just overwrite the configured file to switch out the default background for example if for instance the admin changes the default background, the URL endpoint to that new background will be updated & shouldn't cause issue. It will only be problematic when the endpoint used for the background is the same exact endpoint, for example, `https://example.com/background.jpg` > and emoji images are updated too sometimes (if the pack was revised or to recompress inefficient images). I don’t think we can claim immutability here, at least not for such a long time. the problem here is that 10-30 emojis images are kept being refetched on every textbox interactions, either via the new post or reply field of a post. Emojis images under the same :name: are a bit rare to get updated (unless they're overriding those with the same name, which may require their users to clear cache, however 2w cache should makes sense here), however a pack change should affect literally nothing as the endpoint for emoji pack list are never cached by default.
Owner

It will only be problematic when the endpoint used for the background is the same exact endpoint

Exactly. Once a custom background path was setup admins may just overwrite the file instead of changing config again (implying a need to recompile everything). This is not too uncommon.
Same for emoji. I’ve seen an admin changing an emoji file in place several times now (e.g. because the originally added file turned out to be poorly compressed and way too big).

the problem here is that 10-30 emojis images are kept being refetched on every textbox interactions

This should already not happen and I don’t see it happening on Firefox with the current backend config and nginx reverse proxy. After the initial load, at least for a short while, subsequent appearance of the image and page reloads just use the cached version without even making a revalidation request.
For page reloads this seems to be not fully spec compliant, but apparently browser have started to reduce revalidation on page reloads for almost a decade now to aid mobile data usage and low bandwidth connections. As my test shows, Firefox also doesn’t send a revalidation request for just recently received, fresh cache entries. Presumably they’ll still revalidate eventually, before max-age elapses, else it would already act like immutable and the in-place edits i’ve seen wouldn’t have worked as well as they did.

Even once max-age has passed or something else forces an earlier revalidation, browsers shouldn’t need to fetch the whole image again (if it truly didn’t change), but can just make a revalidation request with If-Modified-Since and receive an empty 304 Not Modified response.
Admittedly I haven’t checked whether our static plug can efficiently handle such revalidation requests, but if not support could be added and will not break in-place upgrades.

> It will only be problematic when the endpoint used for the background is the same exact endpoint Exactly. Once a custom background path was setup admins may just overwrite the file instead of changing config again (implying a need to recompile everything). This is not too uncommon. Same for emoji. I’ve seen an admin changing an emoji file in place several times now *(e.g. because the originally added file turned out to be poorly compressed and way too big)*. > the problem here is that 10-30 emojis images are kept being refetched on every textbox interactions This should already not happen and I don’t see it happening on Firefox with the current backend config and nginx reverse proxy. After the initial load, at least for a short while, subsequent appearance of the image and page reloads just use the cached version without even making a revalidation request. For page reloads this seems to be not fully spec compliant, but apparently browser [have started to reduce revalidation on page reloads for almost a decade now](https://blog.chromium.org/2017/01/reload-reloaded-faster-and-leaner-page_26.html) to aid mobile data usage and low bandwidth connections. As my test shows, Firefox also doesn’t send a revalidation request for just recently received, fresh cache entries. Presumably they’ll still revalidate eventually, before `max-age` elapses, else it would already act like `immutable` and the in-place edits i’ve seen wouldn’t have worked as well as they did. Even once `max-age` has passed or something else forces an earlier revalidation, browsers shouldn’t need to fetch the whole image again (if it truly didn’t change), but can just make a revalidation request with `If-Modified-Since` and receive an empty `304 Not Modified` response. Admittedly I haven’t checked whether our static plug can efficiently handle such revalidation requests, but if not support could be added and will not break in-place upgrades.
Author
Contributor

for some reason, firefox on desktop did exactly that sometimes, however only one time in one session.

firefox on mobile is even worser (than chromium browsers on mobile).

for some reason, firefox on desktop did exactly that sometimes, however only one time in one session. firefox on mobile is even worser (than chromium browsers on mobile).
Author
Contributor

@Oneric wrote in #1068 (comment):

Once a custom background path was setup admins may just overwrite the file instead of changing config again (implying a need to recompile everything)

They can try to upload new background URL via Admin-FE, though. I think a better solution might be needed.

I’ve seen an admin changing an emoji file in place several times now (e.g. because the originally added file turned out to be poorly compressed and way too big).

Shouldn't this only be visible to a limited amount of people? This really depends on how many people that was in the instance itself, So this one will be ambiguous. Even though it's replaced to a compressed one, Real users might barely notice it until they open the emoji lists in full. This is very depends, But if the admin is managing a single user instance, that would be even more different.

One or 10 emoji changes on a pack that people rarely open will barely have this issues.

Still though, I think this is something the admin of the instance need to improve.

@Oneric wrote in https://akkoma.dev/AkkomaGang/akkoma/pulls/1068#issuecomment-16074: > Once a custom background path was setup admins may just overwrite the file instead of changing config again (implying a need to recompile everything) They can try to upload new background URL via Admin-FE, though. I think a better solution might be needed. > I’ve seen an admin changing an emoji file in place several times now _(e.g. because the originally added file turned out to be poorly compressed and way too big)_. Shouldn't this only be visible to a limited amount of people? This really depends on how many people that was in the instance itself, So this one will be ambiguous. Even though it's replaced to a compressed one, Real users might barely notice it until they open the emoji lists in full. This is very depends, But if the admin is managing a single user instance, that would be even more different. One or 10 emoji changes on a pack that people rarely open will barely have this issues. Still though, I think this is something the admin of the instance need to improve.
endpoint: set cache control for favicon.png
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
303ecf83b0
Signed-off-by: Yonle <yonle@proton.me>
Author
Contributor

added a commit that did the same thing for favicon.png endpoint

added a commit that did the same thing for `favicon.png` endpoint
Author
Contributor

days later, i think i've changed my mind and now have different opinion about this one:

@Oneric wrote in #1068 (comment):

Once a custom background path was setup admins may just overwrite the file instead of changing config again (implying a need to recompile everything). This is not too uncommon.
Same for emoji. I’ve seen an admin changing an emoji file in place several times now (e.g. because the originally added file turned out to be poorly compressed and way too big).

I don't think it's tolerable or making any sense to sacrifice user experience just to tolerate admin's mistake. Either we want better user experience with reduced bandwidth usage on less frequent refetching or just this.

days later, i think i've changed my mind and now have different opinion about this one: @Oneric wrote in https://akkoma.dev/AkkomaGang/akkoma/pulls/1068#issuecomment-16074: > Once a custom background path was setup admins may just overwrite the file instead of changing config again (implying a need to recompile everything). This is not too uncommon. > Same for emoji. I’ve seen an admin changing an emoji file in place several times now _(e.g. because the originally added file turned out to be poorly compressed and way too big)_. I don't think it's tolerable or making any sense to sacrifice user experience just to tolerate admin's mistake. Either we want better user experience with reduced bandwidth usage on less frequent refetching or just this.
twitter_api/remote_follow: allow leading @ in nicknames
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
d73fffca0b
And never attempt to fetch nicknames as URLs
Yonle force-pushed cachecontrol-1 from d73fffca0b
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
to 303ecf83b0
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
2026-03-03 05:48:02 +00:00
Compare
endpoint: use favicon plug
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
748bc0e0fb
endpoint: reorder: handle favicon plug first
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
87b2377894
webplug(favicon): remove check on url path.
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
7c494cbe06
Yonle force-pushed cachecontrol-1 from 7c494cbe06
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
to 87b2377894
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
2026-03-05 07:45:21 +00:00
Compare
Yonle changed title from reverse_proxy,endpoint,uploaded_media: add immutable cache-control flag to WIP: reverse_proxy,endpoint,uploaded_media: add immutable cache-control flag 2026-03-05 13:08:10 +00:00
rename favicon plug to favicon_plug, add test
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
e462205d67
Yonle changed title from WIP: reverse_proxy,endpoint,uploaded_media: add immutable cache-control flag to reverse_proxy,endpoint,uploaded_media: add immutable cache-control flag 2026-03-05 19:18:31 +00:00
endpoint: rename the module name for faviconplug
Some checks are pending
ci/woodpecker/pr/test/1 Pipeline is pending approval
ci/woodpecker/pr/test/2 Pipeline is pending approval
f3650efe46
Author
Contributor
  • set immutable flags on certain endpoints
  • also did the same for favicon

todo: fix test

- set immutable flags on certain endpoints - also did the same for favicon todo: fix test
Yonle changed title from reverse_proxy,endpoint,uploaded_media: add immutable cache-control flag to WIP: reverse_proxy,endpoint,uploaded_media: add immutable cache-control flag 2026-03-11 07:24:23 +00:00
Owner

I don't think it's tolerable or making any sense to sacrifice user experience just to tolerate admin's mistake.

The thing is: updating emoji files inplace is not a mistake! Only the proposed change here would turn it into one. Besides the recompression mentioned before, emoji packs can release updated version with some refinements for existing emoji, not only completely new ones.

Also, adding an "immutable" here seems entirely pointless for real-world usage.

First, the "Static" plug we use to serve it already supports cache validation via ETags (enabling browsers to even skip re-downloading past the original max-age unless the file actually changed). Meaning if nothing changed there will be at most a simple revalidation request with a header-only 304 response.
But in practice all modern browsers only revalidate the top-level document on simple reloads instead of everything as the spec originally required. In Firefox this is controlled via the about:config toggle browser.soft_reload.only_force_validate_top_level_document.
Even explicit fetch request from JS just immediately replay the cached 200 response without doing any network request for revalidation if the last revalidation or full fetch is sufficiently recent. You can check this in the network tab. If it immediately lists a 200 response but says "from cache" in the column usually showing how much data was transmitted via the network. It will also list detailed timings for all processing stages a 0ms. Everything is only fetched once across repeated textbox interactions or new post loads for me already and otherwise just replays the cached response. I don’t know when exactly the browser decides a non-immutable resource is old enough to actually perform a revalidation request without a forced cache eviction, but it definitely takes more than a couple minutes. Presumably less than the full max-age of currently 2 weeks though.

Meaning, I cannot reproduce the problem you want to solve with this breaking change to the static endpoint. If you’re seeing duplicated, actual network request for emoji in quick succession, this is likely a bug either in your browser or your reverse proxy setup (e.g. it might strip incoming or outgoing etag, If-None-Match and/or cache-policy headers)

> I don't think it's tolerable or making any sense to sacrifice user experience just to tolerate admin's mistake. The thing is: updating emoji files inplace is **not** a mistake! Only the proposed change here would turn it into one. Besides the recompression mentioned before, emoji packs can release updated version with some refinements for existing emoji, not only completely new ones. Also, adding an "immutable" here seems entirely pointless for real-world usage. First, the "Static" plug we use to serve it already supports cache validation via ETags (enabling browsers to even skip re-downloading past the original max-age unless the file actually changed). Meaning if nothing changed there will be _at most_ a simple revalidation request with a header-only 304 response. But in practice all modern browsers only revalidate the top-level document on simple reloads instead of everything as the spec originally required. In Firefox this is controlled via the `about:config` toggle `browser.soft_reload.only_force_validate_top_level_document`. Even explicit `fetch` request from JS just immediately replay the cached 200 response _without doing any network request for revalidation_ if the last revalidation or full fetch is sufficiently recent. You can check this in the network tab. If it immediately lists a 200 response but says "from cache" in the column usually showing how much data was transmitted via the network. It will also list detailed timings for all processing stages a 0ms. Everything is only fetched _once_ across repeated textbox interactions or new post loads for me already and otherwise just replays the cached response. I don’t know when exactly the browser decides a non-immutable resource is old enough to actually perform a revalidation request without a forced cache eviction, but it definitely takes more than a couple minutes. Presumably less than the full `max-age` of currently 2 weeks though. Meaning, I cannot reproduce the problem you want to solve with this breaking change to the static endpoint. If you’re seeing duplicated, actual network request for emoji in quick succession, this is likely a bug either in your browser or your reverse proxy setup *(e.g. it might strip incoming or outgoing etag, `If-None-Match` and/or cache-policy headers)*
Author
Contributor

@Oneric wrote in #1068 (comment):

updating emoji files inplace is not a mistake

it's never a mistake, but it's also unusual for keeping replacing one after another.

@Oneric wrote in https://akkoma.dev/AkkomaGang/akkoma/pulls/1068#issuecomment-16533: > updating emoji files inplace is **not** a mistake it's never a mistake, but it's also unusual for keeping replacing one after another.
Author
Contributor

@Oneric wrote in #1068 (comment):

adding an "immutable" here seems entirely pointless for real-world usage

i think this is quite pointless to be discussed all along given that not applying this specifically on /media/ by default is some kind of unusual feat. closing.

@Oneric wrote in https://akkoma.dev/AkkomaGang/akkoma/pulls/1068#issuecomment-16533: > adding an "immutable" here seems entirely pointless for real-world usage i think this is quite pointless to be discussed all along given that not applying this specifically on `/media/` by default is some kind of unusual feat. closing.
Yonle closed this pull request 2026-03-28 22:25:18 +00:00
Owner

that not applying this specifically on /media/ by default is some kind of unusual feat

As I wrote in my first reply, it makes sense on /media and the proxy endpoints (even if it probably won’t do too much with modern browsers give nthe results from testing described in the previous post). But the static enpoints are not pointing to immutable content, so here the flag doesn’t make sense, but can degrade things.

Extracted the media and proxy bits into #1096 (i.e. your first commit without changing the InstanceStatic plug)

> that not applying this specifically on /media/ by default is some kind of unusual feat As I wrote in my first reply, it makes sense on `/media` and the proxy endpoints *(even if it probably won’t do too much with modern browsers give nthe results from testing described in the previous post)*. But the static enpoints are _not_ pointing to immutable content, so here the flag doesn’t make sense, but can degrade things. Extracted the media and proxy bits into #1096 (i.e. your first commit without changing the InstanceStatic plug)
Owner

The immutable flags on user-uploaded local media and proxy responses is now merged.

Trying to get rid off unnecessary network traffic to improve the situation on low-bandwidth and/or high-latency networks, or even just for the sake of it are a good goal. But it shouldn’t break existing things. And importantly even with current settings there are no duped network nor revalidation requests for me on ~stock Firefox. This result doesn’t change with Firefox being throttled to 450Kb/s download and 150ms latency. (Again: i observe zero(!) network traffic after the initial download within several minutes (max time i remembered to check again)).
If you see duped refetches and/or revalidations on "every textbox interaction" like you wrote before, then i really think this is an issue in either your instance’s reverse proxy (or media proxy) or browser. It already should only at most perform a rare revalidation. But just in case it was a misreading: requests which are entirely served by the cache and don’t actually cause any network traffic do still show up in Firefox network tab. You can tell them apart by the "from cache" entry in the column otherwise showing how much data was funneled through the network.

If you really want to add an immutable flag anyway, you can still do so either just for your own instance via an override in your reverse proxy, or if you want to see it as a default for all Akkoma instances falsely claiming immutability might at best be feasible if the may-age is greatly reduced. Not sure however if a reduced max-age with immutable might actually end up performing worse in practice than a longer max-age without immutability allowing the browser to sparingly use revalidation requests rather than perhaps ending up refetching the whole content more often. This would need further testing for how often common browsers (at least Firefox and Chromium) actually issue revalidation requests and whether they keep etaged caches around past their max-agefor potential revalidation or just drop it.
(though, if the duped fetches you described are a bug or misconfig of your browser neither helps for non-Akkoma sites)

The immutable flags on user-uploaded local media and proxy responses is now merged. Trying to get rid off unnecessary network traffic to improve the situation on low-bandwidth and/or high-latency networks, or even just for the sake of it are a good goal. But it shouldn’t break existing things. And importantly even with current settings there are _no_ duped network nor revalidation requests for me on ~stock Firefox. This result doesn’t change with Firefox being throttled to 450Kb/s download and 150ms latency. *(Again: i observe zero(!) network traffic after the initial download within several minutes (max time i remembered to check again))*. If you see duped refetches and/or revalidations on "every textbox interaction" like you wrote before, then i really think this is an issue in either your instance’s reverse proxy (or media proxy) or browser. It _already_ should only at most perform a _rare_ revalidation. But just in case it was a misreading: requests which are entirely served by the cache and don’t actually cause any network traffic do still show up in Firefox network tab. You can tell them apart by the "from cache" entry in the column otherwise showing how much data was funneled through the network. If you really want to add an `immutable` flag anyway, you can still do so either just for your own instance via an override in your reverse proxy, or if you want to see it as a default for all Akkoma instances falsely claiming immutability might at best be feasible if the `may-age` is greatly reduced. Not sure however if a reduced `max-age` with `immutable` might actually end up performing worse in practice than a longer `max-age` without immutability allowing the browser to sparingly use revalidation requests rather than perhaps ending up refetching the whole content more often. This would need further testing for how often common browsers *(at least Firefox and Chromium)* actually issue revalidation requests and whether they keep `etag`ed caches around past their `max-age`for potential revalidation or just drop it. *(though, if the duped fetches you described are a bug or misconfig of your browser neither helps for non-Akkoma sites)*
Author
Contributor

my browser is a firefox on arch linux, apparently.

@Oneric wrote in #1068 (comment):

But the static enpoints are not pointing to immutable content, so here the flag doesn’t make sense, but can degrade things.

still, though. Assuming that emoji file gets replaced under the same filename everytime is kinda the wrong assumption that i disagree most of the time, as that change would be really noticeable and there would be rather question to the admins themselves.

my browser is a firefox on arch linux, apparently. @Oneric wrote in https://akkoma.dev/AkkomaGang/akkoma/pulls/1068#issuecomment-16543: > But the static enpoints are _not_ pointing to immutable content, so here the flag doesn’t make sense, but can degrade things. still, though. Assuming that emoji file gets replaced under the same filename everytime is kinda the wrong assumption that i disagree most of the time, as that change would be really noticeable and there would be rather question to the admins themselves.
Author
Contributor

the thing is, if everything that's in instance/static is "not static" under any way, especially favicon.png & emojis (excepting frontend files & anything non medias), i don't think it's really accurate to call it "static" in anyhow.

but if flexibility is also a side goal, maybe making a config for static file header would be making more sense.

the thing is, if everything that's in `instance/static` is "not static" under any way, especially favicon.png & emojis (excepting frontend files & anything non medias), i don't think it's really accurate to call it "static" in anyhow. but if flexibility is also a side goal, maybe making a config for static file header would be making more sense.
Owner

Assuming that emoji file gets replaced under the same filename everytime is kinda the wrong assumption that i disagree most of the time,

It won’t be replaced every time, but neither do browsers revalidate every time. And when changes happen, it shouldn’ŧ take two weeks for them to become visible.

my browser is a firefox on arch linux, apparently.

Have you checked whether the about:config flag i brought up before is set to the correct value? It defaulted to not revalidating non-root docs for me. And also whether cache-related headers all make it through your reverse proxy and/or media proxy (check request/response headers in network tab).
Certain anti-fingerprinting settings might affect this too, as whether a resource is cached or not can be detected and used for fingerprinting (but in that case i’d kinda expect immutable to not make much of a difference)

Also can you share a screenshot of the full width of the network tab (such that all columns are visible), where a duped fetch occurs and with timing details for the later request? (To rule out a misreading of a cache replay as a real network request)

> Assuming that emoji file gets replaced under the same filename everytime is kinda the wrong assumption that i disagree most of the time, It won’t be replaced _every time_, but neither do browsers revalidate every time. And when changes happen, it shouldn’ŧ take two weeks for them to become visible. > my browser is a firefox on arch linux, apparently. Have you checked whether the `about:config` flag i brought up before is set to the correct value? It defaulted to not revalidating non-root docs for me. And also whether cache-related headers all make it through your reverse proxy and/or media proxy (check request/response headers in network tab). Certain anti-fingerprinting settings might affect this too, as whether a resource is cached or not can be detected and used for fingerprinting (but in that case i’d kinda expect `immutable` to not make much of a difference) Also can you share a screenshot of the full width of the network tab (such that all columns are visible), where a duped fetch occurs and with timing details for the later request? (To rule out a misreading of a cache replay as a real network request)
Author
Contributor

the akkoma-fe is still, under certain circumstances still fetching local emojis quite intensive even though these are barely visible yet. i think i will record the network traffic tab once i open my computer later, however mine has immutable on our emoji endpoint so you can then try compare it with yours that doesn't has it. still though, even though a recheck with 302 was done, i think the fact that it still make traffic is still a bit of annoyances. it could be both good or slow.

the akkoma-fe is still, under certain circumstances still fetching local emojis quite intensive even though these are barely visible yet. i think i will record the network traffic tab once i open my computer later, however mine has `immutable` on our emoji endpoint so you can then try compare it with yours that doesn't has it. still though, even though a recheck with 302 was done, i think the fact that it still make traffic is still a bit of annoyances. it could be both good or slow.
Owner

the thing is, if everything that's in instance/static is "not static" under any way, especially favicon.png & emojis (excepting frontend files & anything non medias), i don't think it's really accurate to call it "static" in anyhow.

hmm, the naming here can be confusing yeah, but it’s consistent with how the term is used in general in web stuff. I believe the "static" naming here is in reference to "static webpage" in contrast to "dynamic" content, i.e. content created at runtime either inside the client via WASM or javascript or rendered on the server-side for this request specifically (e.g. via PHP). The static CSS, HTML and (yes also) JS files are the same for everyone, that is unchanging wrt to whom queries them, what they did before and what parameters (other than the path) are supplied to the server — but the files are not necessarily immutable (unchanging over time).
E.g. Pelican and Hugo are "static site generators", that is, they emit HTM, CSS, etc; but the content of those static sites can and does change (e.g. if a new blog post is published, the index HTML page and RSS feeds change in-place and this change is expected to become visible quickly. Yet since no runtime dynamic components are involved it is still considered a static site.

> the thing is, if everything that's in instance/static is "not static" under any way, especially favicon.png & emojis (excepting frontend files & anything non medias), i don't think it's really accurate to call it "static" in anyhow. hmm, the naming here can be confusing yeah, but it’s consistent with how the term is used in general in web stuff. I believe the "static" naming here is in reference to "static webpage" in contrast to "dynamic" content, i.e. content created at runtime either inside the client via WASM or javascript or rendered on the server-side for this request specifically (e.g. via PHP). The static CSS, HTML and (yes also) JS files are the same for everyone, that is unchanging wrt to whom queries them, what they did before and what parameters (other than the path) are supplied to the server — but the files are not necessarily immutable *(unchanging over time)*. E.g. Pelican and Hugo are "static site generators", that is, they emit HTM, CSS, etc; but the _content_ of those static sites can and does change (e.g. if a new blog post is published, the index HTML page and RSS feeds change in-place and this change is expected to become visible quickly. Yet since no runtime dynamic components are involved it is still considered a static site.
Owner

till though, even though a recheck with 302 was done
i think the fact that it still make traffic is still a bit of annoyances. it could be both good or slow.

(I’m guessing you meant 304, not 302 the latter is a redirect response, not anything wrt caches)

How long did it take after the initial fetch before a revalidation was made? As I wrote before, I didn’t even observe revalidation requests, though I also only waited a couple minutes (i configured my browser to clear all client-side data each restart, so I probably can’t test anything taking several days. But your prior description of "every textbox interaction" made it sound like you’re observing this much more frequently anyway)

> till though, even though a recheck with 302 was done > i think the fact that it still make traffic is still a bit of annoyances. it could be both good or slow. (I’m guessing you meant 304, not 302 the latter is a redirect response, not anything wrt caches) How long did it take after the initial fetch before a revalidation was made? As I wrote before, I didn’t even observe revalidation requests, though I also only waited a couple minutes (i configured my browser to clear all client-side data each restart, so I probably can’t test anything taking several days. But your prior description of "every textbox interaction" made it sound like you’re observing this much more frequently anyway)
Author
Contributor

as of the about:config thing that you mentioned, it's set to true by default.

How long did it take after the initial fetch before a revalidation was made

i would say this depends on user connection. when it's slow, it gets refetched than revalidated

anyway, here's the recording. Just a normal refresh. That's the case on my end with immutable being set (notice that some emoji are being fetched 4 times each)

as of the `about:config` thing that you mentioned, it's set to `true` by default. > How long did it take after the initial fetch before a revalidation was made i would say this depends on user connection. when it's slow, it gets refetched than revalidated anyway, here's the recording. Just a normal refresh. That's the case on my end with `immutable` being set (notice that some emoji are being fetched 4 times each) <video src="/attachments/733418e9-c1d9-4385-b467-4a0da92f3ad3" title="Video_2026-03-29_08-25-53" controls></video>
Author
Contributor

well crap, let me encode

well crap, let me encode
Author
Contributor

for some rather strange reason, my video can't be played on forgejo (idk why, probably need faststart? unseekable? dunno), but you can check the video here.

for some rather strange reason, my video can't be played on forgejo (idk why, probably need faststart? unseekable? dunno), but you can check the video [here](https://fedinet.waltuh.cyou/notice/B4jaT5EQPI5HjNhZ56).
Owner

Commented a screenshot to ensure we’ê on the same page how to read the netword tab details.

akkoma_pr1068_networktab_commented

All but the first request for any given emoji are just cache replays and do not cause any network traffic.
(I don’t know how or why it claims a different size for the same, cached file at one point, but that’s unrealted to the caching)

On initial page load I only see a pair of two requests (one img initiator and one fetch from still image detection) not four like you seem to get, notably even at the frontend of your own instance with the logged-out defaults. This is probably some FE setting.
But apart from this, all but the first request just being cache replays is already true for me too just with cache-control public, max-age=1209600. And the cache persists at least 30min (max i just tested) without any revalidation request being done (except if i navigate directly to the image URL as them main document of the tab).

With Chromium it appears to behave the same, though i didn’t leave it running for 30min yet there.

If this differed for you without immutable, you might want to check if perhaps your reverse proxy messed with non-immutable cache-control headers or whether it’s some (possibly preset by your distro) browser config option. You can also try going to some other Akkoma instance which doesn't set immutable.

Commented a screenshot to ensure we’ê on the same page how to read the netword tab details. ![akkoma_pr1068_networktab_commented](/attachments/aeaeb0d3-f415-4a5d-a7f2-40b659d53e4f) All but the first request for any given emoji are just cache replays and do not cause any network traffic. *(I don’t know how or why it claims a different size for the same, cached file at one point, but that’s unrealted to the caching)* On initial page load I only see a pair of two requests (one `img` initiator and one `fetch` from still image detection) not four like you seem to get, notably even at the frontend of your own instance with the logged-out defaults. This is probably some FE setting. But apart from this, all but the first request just being cache replays is already true for me too just with `cache-control public, max-age=1209600`. And the cache persists at least 30min (max i just tested) without any revalidation request being done (except if i navigate directly to the image URL as them main document of the tab). With Chromium it appears to behave the same, though i didn’t leave it running for 30min yet there. If this differed for you without `immutable`, you might want to check if perhaps your reverse proxy messed with non-immutable `cache-control` headers or whether it’s some (possibly preset by your distro) browser config option. You can also try going to some other Akkoma instance which doesn't set `immutable`.
Author
Contributor

as of now, the cache-control header is no longer being set on the reverse proxy but rather on the akkoma-be that's running in my instance. i will give a little comparison later.

as of now, the cache-control header is no longer being set on the reverse proxy but rather on the akkoma-be that's running in my instance. i will give a little comparison later.
Author
Contributor

back from the other instance, so apparently:

  • /emoji/ endpoint seems to cache and refetch properly even with no immutable tag, however,
  • /favicon.png is no-cache. so even with 304 response, the favicon will still be displayed after we got the 304. this one is still a bit of a problem, so we can try address this.

strangely, during the time when i'm still in vanilla akkoma-fe, for some reason:

  • /emoji/ fetched the same .png more than 1 times (as of my recording, it can be 4 times each). it could be due to the emoji being used by 4 <Status> in the FE (notification, notes, etc).
back from the other instance, so apparently: - /emoji/ endpoint seems to cache and refetch properly even with no `immutable` tag, however, - `/favicon.png` is `no-cache`. so even with `304` response, the favicon will still be displayed after we got the 304. this one is still a bit of a problem, so we can try address this. strangely, during the time when i'm still in vanilla akkoma-fe, for some reason: - /emoji/ fetched the same .png more than 1 times (as of my recording, it can be 4 times each). it could be due to the emoji being used by 4 `<Status>` in the FE (notification, notes, etc).
Owner

/favicon.png is no-cache. so even with 304 response, the favicon will still be displayed after we got the 304.

It should probably allow caching without revalidation, yes. In theory this would be an improvement (but does not need an entire new plug module)

In practice we’ve got a funny situation though, presumably from browser treating favicon specially:

  • Firefox appears to ignore the required revalidation from no-cache and just replays the unvalidated cached favicon anyway. EDIT: coorection: it only used unvalidated caches for request very close to the original one. A reload a little bit later does in fact cause a 304 revalidation. The revalidation does even happen for public, max-age=…, immutable
  • Chromium keeps always revalidating (304) the favicon even with public, max-age=1209600, immutable (tested against fedinet.waltuh.cyou)
  • WebKit appears to always refetch (200 with substantial network traffic) the entire image for either version of the cache-control header

Meaning, in practice, nothing will change and the benefit is purely theoretical.

> `/favicon.png` is no-cache. so even with 304 response, the favicon will still be displayed after we got the 304. It should probably allow caching without revalidation, yes. In theory this would be an improvement (but does not need an entire new plug module) In practice we’ve got a funny situation though, presumably from browser treating favicon specially: - Firefox appears to ignore the required revalidation from `no-cache` and just replays the unvalidated cached favicon anyway. **EDIT:** coorection: it only used unvalidated caches for request very close to the original one. A reload a little bit later does in fact cause a 304 revalidation. The revalidation does even happen for `public, max-age=…, immutable` - Chromium keeps always revalidating (304) the favicon even with `public, max-age=1209600, immutable` (tested against fedinet.waltuh.cyou) - WebKit appears to always refetch (200 with substantial network traffic) the entire image for either version of the cache-control header Meaning, in practice, nothing will change and the benefit is purely theoretical.
Author
Contributor

@Oneric wrote in #1068 (comment):

/favicon.png is no-cache. so even with 304 response, the favicon will still be displayed after we got the 304.

It should probably allow caching without revalidation, yes. In theory this would be an improvement (but does not need an entire new plug module)

apparently, when porting this to pleroma-be, phnt pointed out that for favicon endpoint, it checks 2 things at once (or similar):

  • <staticdir>/favicon.png
  • priv/instance/static/favicon.png

hence the existence of separate favicon plug

@Oneric wrote in https://akkoma.dev/AkkomaGang/akkoma/pulls/1068#issuecomment-16563: > > `/favicon.png` is no-cache. so even with 304 response, the favicon will still be displayed after we got the 304. > > It should probably allow caching without revalidation, yes. In theory this would be an improvement (but does not need an entire new plug module) apparently, when porting this to pleroma-be, phnt pointed out that for favicon endpoint, it checks 2 things at once (or similar): - `<staticdir>/favicon.png` - `priv/instance/static/favicon.png` hence the existence of separate favicon plug
Author
Contributor

@Oneric wrote in #1068 (comment):

  • WebKit appears to always refetch (200 with substantial network traffic) the entire image for either version of the cache-control header

apple being at it again.

interesting observation.

@Oneric wrote in https://akkoma.dev/AkkomaGang/akkoma/pulls/1068#issuecomment-16563: > * WebKit appears to always refetch (200 with substantial network traffic) the entire image for either version of the cache-control header apple being at it again. interesting observation.
Owner

it checks 2 things at once (or similar): […] hence the existence of separate favicon plug

The existing InstanceStatic module already takes care of that (that’s how it can handle it atm), it can simply be reused for another plug, just with different initialisation args. Probably it could even just be added to the same plug currently taking care of emoji and static images, to get (in theory) the same, only rare revalidation

But while it makes sense in principle, in practice there’s no point anyway as all browsers still force revalidations or even full redownloads disregarding cache-control headers. We could still move it to the emoji/image plug (adjusting only) in case browsers ever drop this favicon special casing in the future

> it checks 2 things at once (or similar): […] hence the existence of separate favicon plug The existing `InstanceStatic` module already takes care of that *(that’s how it can handle it atm)*, it can simply be reused for another plug, just with different initialisation args. Probably it could even just be added to the same plug currently taking care of emoji and static images, to get (in theory) the same, only rare revalidation But while it makes sense in principle, in practice there’s no point anyway as all browsers still force revalidations or even full redownloads disregarding cache-control headers. We could still move it to the emoji/image plug *(adjusting `only`)* in case browsers ever drop this favicon special casing in the future

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
AkkomaGang/akkoma!1068
No description provided.