Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

max-age and stale-while-revalidate parameters #4

Open
mnot opened this issue Aug 18, 2014 · 7 comments
Open

max-age and stale-while-revalidate parameters #4

mnot opened this issue Aug 18, 2014 · 7 comments

Comments

@mnot
Copy link

mnot commented Aug 18, 2014

I remain pretty ambivalent about these; it's information that the server can discover in another way (e.g., by remembering what values it sent and associating them with an ETag; it'll come back on revalidation requests in If-None-Match already), and it's pretty verbose to be putting on all revalidation requests.

The perf impact is not small; bigger headers on requests has a disproportionate effect on performance.

Has the ETag strategy been considered?

(Part of my pushback, BTW, is that I'd like to see cache information like age for all requests, not just SwR-initiated ones; this helps the origin tune their policy overall).

@KenjiBaheux
Copy link
Owner

We believe that using etag would not work well.

If you are using etag to keep track of the "request time", original max-age as well as original s-w-r in order to determine the resource's age and whether or not the revalidation is async, you will have to send a new etag on 304s. In which case, Chrome doesn't work as intended (the cache won't be updated if the etags don't match anymore).

If you are using etag as an id to a server side database (in which you keep track of request time, max-age and s-w-r), we think that we would run into issues with proxies:
user A gets resource X with etag=12345678 at time T
user B gets resource X with etag=1234568 at time T+1
user A's resource X goes stale at time T+2, we update the database.
user B's resource X goes stale at time T+5, we update the database but we don't know if age is T+5 - T+1 or T+5 - T+2...

What do you think?

We would like to have cache information like age, max-age and s-w-r (if relevant) for all requests but in that case we should probably make this opt-in. Would something like "cache-control: max-age=3600, send-freshness" to turn it on and "cache-control: max-age=3600, dont-send-freshness" to turn it off* makes sense?

*: obviously the names are too long but tentative.

@KenjiBaheux
Copy link
Owner

@mnot (explicit to/ just in case)

@mnot
Copy link
Author

mnot commented Aug 27, 2014

You'd still get the age from the Resource-Freshness^H^H^H^H^H Freshness request header, so you'd know when it was inserted into cache. You could also have a flag to indicate that a request was async.

@KenjiBaheux
Copy link
Owner

@mnot Thanks for the quick reply.

I see, so basically you will:

  1. keep re-using the ETAG as an id tied to a particular set of max-age and stale-while-revalidate
  2. use the Freshness header to know the age of the asset

With 2 and 1 combined with the user-agent header you should be able to infer if the request was async or not (e.g. assuming a knowledge of the s-w-r compliant user agents).

Perhaps in that case, since age is the only information we ever send back, we probably ought to re-use the "Age" header. Would that be controversial?

I'll ask for feedback from the folks who are running/eager to run experiments for their take on how much burden this would be.

As explained in my previous comment, I think the alternative to this would be to make the full Freshness header opt-in: it seems easier to start and stop an experiment as there is no need to setup an ETAG scheme or a database, you can also control if and how the Freshness data comes in (e.g. only for a few %age of users, only for a specific criteria such as mobile UA or a specific country...).

@mnot
Copy link
Author

mnot commented Sep 1, 2014

I think the tradeoff is between more work on the server-side that wants to do this kind of tracking, a/b testing (because they need to either keep some state on the different headers they've sent, or have a fair amount of discipline regarding changes to them) and the amount of information that clients send in requests.

Personally, I think it's reasonable to cause more work on the server side, because sending the information in each request has a pretty heavy impact upon perf (at least in HTTP/1).

Regarding using the "age" header -- you could, but to do so properly, you'd need to update the semantics of the Age header, which means a standards-track document (since it's defined in a standards-track RFC).

Additionally, people (including me!) push back on having a single header mean different things depending on which direction it's going; this confuses people (e.g., see Cache-Control).

So, it'd be much easier to define a new header to do this, rather than using Age.

Can I suggest something like Cache-Info or even just CI? I think there is going to be more than just age that we want to expose, over time.

I'd be happy to spec it up if it helps.

@igrigorik
Copy link
Collaborator

@mnot this may be a bit of a tangent, but I'd be curious to see if we can come up with a "Cache-Info" spec that could be used both at the HTTP layer and directly on the client - i.e. as part of Nav/Resource Timing API's. I think there are good use cases for both, and I'd argue that we would want to expose same data at both layers anyway... and I believe you had some thoughts on NavTiming use case as well. :)

Also, assuming CI or some such header existed, we could send it on opt-in basis? Mapping this to CH example, it could be Accept-CI with list of values that you're interested in? And on that subject, perhaps its worth defining some shared language around opt-in headers? Is Accept-X specced anywhere? Some consistency would go a long way here.

@KenjiBaheux
Copy link
Owner

@mnot re CI, I think we should go for it.
Would it be practical for you to use github (this repo or one one of your own)? I think it would be quite effective for Ilya, myself and other interested parties to participate if the work was done on github.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants