9 ms·
New HTTP standards for caching on the modern web
- sdze 5y agoBuild leaner websites and don't overcomplicate things. You won't need CDNs and data-kraken like Cloudflare & Co.
- Cthulhu_ 5y agoA lean website (they call out haveibeenpwned) can still get billions of hits. CDNs were initially conceived to help with international / intercontinental latency, which you can't fix by having a leaner website. And there's a heap of problems to solve that you can either spend your own valuable time on, or outsource to a specialist.
- friseurtermin 5y agoLeaner websites can only reduce bandwidth strain, there's no impact on latency, right?
- forgotmypw17 5y agoOne challenge I've experienced recently is I can't figure out how to hint to the browser that it should refresh a particular cached page. (Without appending ?time=1634851491 to the URL.) For example, let's say I've already cached the page /new.html Now, I click a button which triggers a change to the page, and I am redirected back to it. Even though the page has changed, and the browser should see a new timestamp in the header if pinging the server, it just doesn't seem to happen. Has anyone dealt with this before? I tried to ask on StackOverflow, but lately my questions don't seem to get any attention, and I've run out of reputation to spend on bounties.
- bawolff 5y agoCache-Control: max-age=0, must-revalidate Sounds like what you want (presuming your server handles 304 logic correctly)
- forgotmypw17 5y agoI do want caching to happen, however -- until something changes the page.
- bawolff 5y agoThat directive says - cache, but ask the webserver if the page has changed every time. If the server responds 304 not modified, it uses the cached version. From a performance perspective though, people on good internet might be dominated by RTT so a 304 might be almost as expensive as a full 200.
- ryanpetrich 5y agoThis is what ETags are for. Upon a user's first visit the server should return an ETag uniquely representing the current version of the page. The browser will cache both the page and the tag. Upon subsequent page visits the browser will send an If-None-Match header containing the tag for the version of the page it has cached. The server should compare the incoming tag with the tag for the current version and return a "304 Not Modified" response if the tags match or a full response with the newer tag in the ETag header if they don't.
- tshaddox 5y agoYeah, and it works the same way with If-Modified-Since and Last-Modified.
- bandie91 5y agoa drawback of relying on ETag is that if a page is visited frequently, then the cache validation "If-None-Match" request still being sent and takes bw+latency+computation+etc and I suspect that if the connection is broken or status 503/504 is responded, then neither the cached page is shown. my understanding is that he whant to refresh the page only if it's known to be changed and always use the cached version otherwise.
- tyingq 5y agoIt's a combination of different headers that's hard to sum up in a short comment. A good article on the subject should talk about all these headers: Expires, Cache-control, Etag, Pragma, Vary, Last-Modified Key CDN has an article on it. They certainly would have experience and expertise there. I didn't read the whole thing, but it seems to have it covered: https://www.keycdn.com/blog/http-cache-headers https://www.keycdn.com/blog/http-cache-headers There's also some interesting exceptions where rules aren't followed. Like browsers typically have a completely separate cache for favicons. I suppose because they use the icons in funny/different ways, like bookmarks. There are also sometimes proxies (especially corporate MITM ones) that don't follow the rules. Hence the popularity of cache-busting parameters like you described.
- djbusby 5y agoI get the desired effect without Expires and Pragma, primarily using Cache-Control: no-store (or something I copied from MDN).
- nesarkvechnep 5y agoBut no-store makes the resource uncacheable by both intermediate caches and browsers.
- bandie91 5y agoas of my understanding of the original design of HTTP, each HTTP resource may state how long itself can be cached in the response header; and the client (browser, proxy, etc) does not have to re-request the resource before the expiry. this is the sandard, so you can not hint that a resource has to be revalidated - in standard way. obviously since then, several tricks emerged, like your mentioned timestamped URL approach - however i'm not sure upto what extent is it standardized in clients to understand that "/path?query" is somehow related to "/path", because originally the request string (path and url parameters) was opaque to the http client, so they should be cached independently. things obviously changed since then. the method i use is to fire a request to the URL which has to be refreshed by Ajax (XHR) with Cache-Control header (yes, it is a request header too), then display the response content or redirect to it.
- scottlamb 5y ago> however i'm not sure upto what extent is it standardized in clients to understand that "/path?query" is somehow related to "/path", because originally the request string (path and url parameters) was opaque to the http client, so they should be cached independently. things obviously changed since then. It hasn't changed. Those two URLs are still cached completely independently by the user agent. The ?time=... cache busting trick is meant to produce a cache key that's never been used before, thus requiring a fresh request. The new request doesn't clean up the cache entries for the old URLs; it just doesn't use them. That's one reason it's better to use etag and such to make the caches work properly, rather than fight them with this trick. On many servers, if new.html is a static file, the same entity is produced regardless of parameters. But the user agent doesn't know this.
- bandie91 5y agoyes, thanks for clarification. my impression that /path and /path?parameter were handled in relation of each other is because some proxy added an option to do so. but good to know that user agents does not.
- toast0 5y agoThere's no standard way for one page to invalidate another. I've seen some private patches to do it in squid, but that doesn't help because you want to do it for browsers. Your options are probably: a) redirect to a different URL as you've done by appending stuff to it b) require revalidation on each request, recipies shown by other posters c) POST to the url you want refreshed; post isn't cachable. Note that you can't redirect to POST somewhere else, but you can do it with javascript. d) use XHR to force a request as another poster mentioned.
- inside65 5y agoI have this same issue and have been working around it by appending to the URL. I'd like to believe there's a better way, but I don't know what it is. Alternatively, I could just disable caching but that would defeat the point.
- bobbylarrybobby 5y agoOn Macs, in Safari, cmd-opt-R is “reload page from origin”, which I believe ignores cache
- nesarkvechnep 5y agoThere's no easy way. One way is to use `max-age=0, must-revalidate` but then your origin server should be optimized for conditional GET requests. It's a very tricky balance between origin server load and consistency. By deciding to use HTTP cache you agree to eventual consistency and this decision comes with its upsides and downsides. There has been a proposal in 2007 for a thing called cache channels. It defined a mechanism for an origin server to expose a feed which caches would poll at an interval. The feed would list resources that have gone stale since the last query. This mechanism in conjunction with conditional GET requests would've solved part of the issue of hinting browsers to invalidate their local resources.
- scottlamb 5y agoI appreciate that the Cache-Status: header they describe uses RFC 8941 structured fields and thus ";" to separate items within each cache and "," between caches. It's like someone put effort into making it easy to parse. Rant time: I just finished writing a state machine parser for "WWW-Authenticate:" and "Proxy-Authenticate:". Those headers use comma both to separate challenges and to separate parameters within a challenge, which just seems mean-spirited. Other things about HTTP authentication that seem mean, dumb, annoying, or all of the above: both the RFC 2069 example response and the RFC 7616 SHA-512-256 example response are calculated incorrectly; RFC 7616's userhash field seems to require the server to do O(users_in_database) hashes to know what user to operate on; RFC 7235's challenge grammar describes a token68 syntax that really only is used for the credentials in basic, never a challenge; RFC 7616 drops backwards compatibility for RFC 2069 even though I bought a product this year that still uses RFC 2069-style calculations; and it's based on old standards that followed "be conservative in what you do, be liberal in what you accept from others" so RFC 7230 section 7 has separate grammars for what lists you must send and what lists you must accept, which further complicates parsing the nested lists.
- nmadden 5y agoDigest should just die. It’s a terrible standard that makes it essential impossible to store passwords securely on the server.
- scottlamb 5y ago100% agree. It's like when you call into phone support and the person on the other end obviously can see your plaintext password. I'm working with IP security cameras, and the ONVIF standards [1] actually mandate Digest. I own cameras that only support HTTP Digest Authentication for RTSP. I'd tell the ONVIF folks this is dumb, but I don't want to pay $10,000/year for that privilege. [2] The only saving grace is that they aren't "real user" passwords, and you can isolate the cameras to a network segment where only the NVR can talk to them and vice versa. (And the NVR needs to keep the plaintext password anyway.) [1] https://www.onvif.org/profiles/specifications/ https://www.onvif.org/profiles/specifications/ [2] https://www.onvif.org/join-us/membership-levels/ https://www.onvif.org/join-us/membership-levels/
- simonw 5y agoReally good article - I hadn't heard about either of these headers and I really appreciated the clear explanation of both.
- deleted 5y ago[deleted]
- jayd16 5y agoAre there any standards for signed but cacheable http content? Seems like that's a tool that's missing from our toolbox (unless anyone can enlighten me.) Seems like something as simple as that could do most of the job IPFS is setting out to do, for example.
- SquareWheel 5y agoIt sounds like you're describing Signed HTTP Exchanges (SXG). https://developers.google.com/web/updates/2018/11/signed-exchanges https://developers.google.com/web/updates/2018/11/signed-exc...
- bryans 5y agoWe really need a way to tell the browser NOT to access or return the cache if the server returns a 304. There are so many situations where stale data just gets discarded because it's not actually useful, but the browser still goes through the motions of accessing the disk, storing in memory and then garbage collecting immediately. The browsers' only existing capabilities are to naively assume that we still need to process that file in some way, but the only thing accomplished is using some electricity.
- potamic 5y agoI didn't quite understand the fundamental need behind this. While the article has explained to the extent that it will help determine who returned the cache or it will help specify who can cache, but what I don't get is why would I be interested in this? My mental model of the internet has clients and servers. Clients will talk to servers, perhaps through intermediaries, but intermediaries are also clients and servers playing appropriate role depending on the direction of data. A server doesn't need to know where a request is coming from and a client doesn't need to know who is sending it. It's a very elegant and powerful model that allows for a great deal of flexibility. This standard appears to treat intermediaries as a first class concern with special agency. Which means clients and servers will start handling intermediaries differently. It's a complicated and restrictive architecture overall and am not sure if it's a good idea. Was there anything fundamentally broken with the current caching mechanisms that called for this?
- wh33zle 5y agoThe architecture of the web (REST), always had intermediaries as first-class citizens. I can recommend reading into Fielding's dissertation! The declarative and stateless message design is partly motivated by the need for intermediaries processing and understanding the messages (ie POST must not be cached f.e.). I think the introduction explained it very well: The original design generalized too much for the needs of 2021 by putting all caches into a single bucket.
- potamic 5y agoIt recognized the need for intermediaries sure, but I don't believe it treated them as first class citizens. The idea has always been to treat them as proxies. Proxies extend/enhance the behaviour of a certain process without changing the interfaces. This particular standard changes those interfaces by treating proxy communication different to target communication.
- e12e 5y agoThe thesis: https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm Of cache, see eg: https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#fig_5_10 https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arc... > Layered system constraints allow intermediaries--proxies, gateways, and firewalls--to be introduced at various points in the communication without changing the interfaces between components, thus allowing them to assist in communication translation or improve performance via large-scale, shared caching. With REST (and without encryption or with trusted ssl stripping proxies) you can have a lan level cache - eg: if one of your 10 000 students access Fielding's thesis, that might be locally available for the potential 9 999 next requests. Typically this was useful for caching news site front pages - and could in theory work for video content too).
- bborud 5y agoCan we stop calling things "modern"? We're talking about the web. A constantly changing, bubbling soup of protocols, software, ideas, and practices cobbled together with duct-tape and spit. The word "modern" has no meaningful definition as it doesn't belong to any identifiable point along the timeline.
- afiori 5y agoHere modern is not description of the RFC iteself, modern web = today's web https://www.etymonline.com/search?q=modern https://www.etymonline.com/search?q=modern > In history, in the broadest sense, opposed to ancient and medieval, but often in more limited use. In Shakespeare, often with a sense of "every-day, ordinary, commonplace." Meaning "not antiquated or obsolete, in harmony with present ways" is by 1808.