Conf42 Cloud Native 2023 - Online

What’s next in the HTTP caching world

Video size:


Since HTTP 1.1, we have the Cache-Control HTTP header to manage the cache flow mechanism. During the HTTP/2 and HTTP/3 developments, there was a lot of draft RFC to add more standards on the servers. See together the improvements and the new features that can be used to deal with the HTTP cache.


  • Silver Kombrak: How to accelerate your APIs or your web writes using only the HTTP features. RFC 20 616 or also known as HTTP 1.1 was the first RFC to really standardize things. Caching would be useless if it didn't significantly improve performances.
  • RFC 724434 2014 sorry as known as the HTTP one one caching will add more context and more details and more use cases to the previous caching RFC and will invalidate them. In June 2022 I was in Greece, but Mark Notingham released two rfcs to the cache status RFC and the targeted cache control HTTP Eater.


This transcript was autogenerated. To make changes, submit a PR.
Hello everybody, thanks for joining me to this conference. For the next 30 minutes we will talk together about the past, the present, and the future of the HTTP cache. Let's see together how to accelerate your APIs or your web writes using only the HTTP features. So first let me introduce myself. My name is Silver Kombrak. I'm a freelance goling architect and the creator of the HTTP cache tool called Swamp. I'm also a french baguette, so sorry for my baguette accent. And I'm the maintainer of the Caddy cache on lure module and an active open source contributor. By the way, you can find me on GitHub caching Darkwick and on Twitter searching Darkwick underscore dev. So we have to go back in time. Near the end of 1998, HTTP 10 was released for two years, but the chaos between each providers, like Google or Akamai because of HTTP 10 wasn't as extensible as they wanted. So they implemented some other features on their own way, and it was really painful to support each provider, all providers with all of their features and all of their specific features. So HTTP 1.0 didn't explain in depth what is a request, a response, an HTTP either, or a comment in your HTTP request, for example. And it didn't explain the way to handle and manage the incoming data or what is prohibited, and let the providers be free of the implementation. In June 1999, Matrix, the first movie was released to theaters. We discovered Neo and the red and blue pills. Meanwhile, webfathers started to write and release an RFC to standardize. HTTP 1.1 RFC is for request for comments, and it's like a big budget blog that define how a protocol must work and its code is RFC 20 616 or also known as HTTP 1.1 was. It's the very first RFC to really standardize things. It will define the grammar. So what's an HTTP eater, what resource identifier and on UI that tells one URL must match to one thing on your server. It will also define what is an HTTP request, how to build it, which parts can receive comments, which parts must be by the server, and it defines most of the HTTP users always used nowadays. More specifically in this RFC, there is an interesting part about the caching in HTTP, and it's the first try to standards that and it starts with the following sentence. Caching would be useless if it didn't significantly improve performances. That means if your cache server responds slower than your upstream, you don't need this cache server. But nowadays there are some other points if your cache server is more energy energy consuming than the upstream, or is more cost expensive than the upstream. You may not need a cache server too. We can't only take in consideration the power and the speed to serve the data, as it's the first standard, there are some missing points, like the following. If a stored response is not fresh enough, the cache may still return the response with the appropriated warning eater first. Who knew the warning HTTP either existence to be honest, I discovered that by reading this rfc, and I'm pretty sure most of recent applications doesn't choose that either. But that's a back order from the past. And the most weird part is that the cache can return a not fresh enough response, so you are free to return a cache response to your client, even if it's considered as Taylor the RFC 20 616 introduced the cache control HTTP Eater and its own directives. There are the common directives that can be used in the request and the response context. The wellknown no cache directive won't use a cache response in the request context, and won't store the specified response either. In the response context, the no store directive won't store the upstream response. The max edge will tell to the cache server to store that for at most x seconds in the response context and in the request context, it should return the cache response only if it's stored for less than x seconds. The not transform directive will tell to the cache to not try to transform the request or the response. Depending the context. It should not remove or add extra editors and not try to jzip the response to reduce its size. The request or the response must stay unchanged. The HTTP request cache control directive contains the max tail to explain okay, you can serve a stale response that means not fresh enough and is that stale since x second less than x second. The Minfresh directive is not really used in production because it's here to be able to tell to the cache okay, serve the stored response only if it's stored since at least x seconds, so you cannot have a stored response that is fresher than x second. I don't have the use case for that I don't know, and only if cached directive serves the cached response only if it's present in the storage. So if your storage was a storage response, it will serve it even if it's tail or anything else. The HTTP response cache control directive contains the public that ensure the response can be stored by the shared cache, and opposed to that, the private that can be stored only by the private caches. Like the browser, the must and proxy will revalidate the response with the upstream and if no errors appears, it will return the stored response to the client and the fmaxage will manage the stored duration on shared cache. There is a last directive named cache extension. This directive allows the user to add more custom directives only understood by the cache system itself. The first example, add the extension community with the value UCI. The cache system could increase the time to live for the response storage if the value is UCI, for example. And that's the same for only if my case match with the given value that should. So during the summer 2001 major improvement has been made. That's not the loft winners, but that's ESI language. To be honest, this is not a validated rfc, but it's currently accepted by the w three C and integrated in most of your CDN or cache servers. The ESI language allows the templates, cache the templates and only request the dynamic parts. In this example we request the article HTML content and this page have a static article and a dynamic header called user PHP. The ESI processor here varnish will get from its cache the article HTML file, parse it, and will see there is an ESI tag and will process it. It will send a request to the user PHp endpoints on the upstream server, grab the response and replace in the article HTML body the ASI tag by the user php received value if you already wrote some HTML, you'll find that easy to use. And as the tag is not understood by the browser, it won't be shown to the end user or display an additional div if it cannot be processed. So it's really transparent to the user unless it tries to read the source code of the received HTML file. Here the ESI include tag will request the source attribute here example one HTML if it throws an error while doing the request this request, it will request the alternateback example two HTML and if we set the on error property with the value continue, it will just ignore the errors. A more complex one we can do some try catches the ESI try will try was its name the attempt sub block if can error occurs in this block, it will just process the ESI accept tag. You can see at the lines three and seven some ESI comments that should be removed by the ESI processor. Even you return them to the browser. Even if you return them to the browser, it will only increase the body size, but your browser won't interpret them, won't display them, et cetera. You can also load some variables from the request and more precisely from the request cookies or request host request path and some predefined variables. And using the ESI vars, sorry, we will generate the image HTML tag. The computed source will take the value from the cookie name type. Imagine we set human as a value in the type cookie, your source and your alt will contain and your user, your end user will see only the computed image HTML tag. So that's demo time. So that is demo time to show you a more complex example and to prove that very powerful. So I will use caddy was a proxy. So here is caddy file here up. My proxy will be running on the HTTP port. I said okay that's 80 and the common HTTP port and I have some routes that return ESI tags here I have a server route to proxy to a server. The request that will serve also its own HTML or HTTP response and all unmatched pattern here will try to load the features and will compute the response because of the ESI directive in the woodblock here that's cadify syntax. But it's really easy to understand and it's easier than the Nginx config or Apache configuration. Okay, in the features I have the complex example here named full HTML that contains all ESI tags. We have some variables interpretations, some include some escaped contents and many other cases. So if I run the caddy server here make run, okay it will take some seconds to build that, I think. And it run it here. So my Kg is running and here make run server. So it will go in the middleware and just run main go for make run server and in Kadi it will run, make run here make build and make run. So it will build the ESi module for KG from the sources. So I have my two servers here and if I try to request it, I can now send can HTTP request to the servers pass for example. So, that's a local domain. I edited my host on my laptop for that. And if I send on server, yes I would like you to use curl for that. So it returns the readers because in the main go I'm flushing the response each time I'm writing something and I wait 9 seconds in total and it will take whats HTML code and we'll pass the ESI include here, here it's an escaped content from ESI and I'm removing this include and I'm using HTTP host here. So we have that in the response and the more complex example because here it's a bit simple I can say okay, try to load full HTML and okay, why? Okay, it's the demo effect. I think we will debug that together. Why that's this port here and if I retry it works. Okay, so it works and I have my tags and other things. Okay, I think I show you everything so I hope you enjoyed the demo. So we we will jump some years later and go at the summer 2014. That's the year the new Zelda EwOL warriors was released also. But some people prefer to write and publish RFC during their holidays instead of chilling. And the RFC 724434 2014 sorry as known as the HTTP one one caching will add more context and more details and more use cases to the previous caching RFC and will invalidate them. First of all, we got a new HTTP response eater called age. The age Eater explicits the number of seconds the response is stored. The second example should not occur. It should take the max between your edge, your either edge and zero so it details the cache invalidation. Imagine you store your getresponse because it has to contact the database and that's IO consuming, et cetera. If you build an rest API, you'll have the same path but only the verb differ to manage your resource. If you send a get request on books one, for example, you will store your response and after that if you send one of put, post or delete HTTP request on your resource, you'll have to invalidate your stored getresponse for this resource id because these HTTP verbs will alterate your stored resource. This RFC adds a new HTTP request cache control directive named Stalewire validate. This one allows the cache server to serve a stale response and try to revalidate in the background with the upstream and store the freshly response and replace the stale one that ensure client will receive data even if your upstream is done. Add this leader to every request when you think it's okay, even if your clients have some stale data. In June 2022 I was in Greece, but Mark Notingham decided to release two rfcs to the cache status RFC and the targeted cache control HTTP Eater about the cache status Eder. It defines some useful directives. The first one is it and I missed that. You can now detect if it was it by your cache server or missed forward. Add more context about the cache server that forwards the request to the upstream forward statues returns the statues from the upstream or another cache server. The TTL shows how many seconds the cache response will be considered as fresh. By the way, the edge eater plus the TTL should be equal to your storage duration and must be equal to that. The collapsed directive tell you if the response has been built from one part of the cache response and the second part from the upstream. For example the key give you the stored key in your cache index and the detail give you some details from. For example, if it's not stored because the response storage is unreachable, so the cache whats you see there is like that. You have your server cache name if it's it or not. If it's it, you have a TTL, you can have the key, et cetera. And in the last one example you have the case that the storage is unreachable. Now the targeted cache control RFC allow you to manage automatically the cache control. Imagine this infrastructure. Your client would send a request to your servers. His request goes through the CDN and it will proxy to your varnish cache server. It will send the request to your CAD instance that will transfer to the upstream so the upstream returns a response with four headers, the well known cache control, the CDN cache control, the varnish cache control, and the KD cache control with their own duration, their own storage directive. Imagine you can have for the CDN cache control private directive, and the caddy instance will check if the Caddy cache controller is present and will store the response for 1 hour. Then varnish will store for five minutes and the CDN will store for will store the response for two minutes, and the client will store that, but won't use it because of the no cache directive. And if the wildcard cache control either is present and interpreted by your cache. For example, imagine varnish doesn't recognize the varnish cache control. It should, and it must fall back on the basic cache control either. And here our clients will store it, but won't use it because of the no cache. Okay, thank you for your attention. Thank you to the organizers team. Don't hesitate to ask your question if you have any, and I hope you found that interesting.

Sylvain Combraque

Consultant Go & ReactJS

Sylvain Combraque's LinkedIn account Sylvain Combraque's twitter account

Awesome tech events for

Priority access to all content

Video hallway track

Community chat

Exclusive promotions and giveaways