3

In the presentation "Cache is King" by Steve Souders (at around 14:30), it is implied that there are in practice only two caching durations that you should use for your resources: "forever" and "never" (my own terminology).

  • "Forever" means that you effectively make the resource permanently immutable by setting a very high max age, such as one year. If you want to modify the resource at some point, the presentation suggests, you simply publish the modified resource at a different URL. (It is suggested that this renaming is necessary, in part or entirely, because of the large number of misconfigured proxies on the Internet.)
  • "Never" means that you effectively disable all forms of caching and require browsers to download the resource every time it is requested.

On the one hand, any performance advice given by the head performance engineer at Google carries weight on its own. On the other hand, HTTP caching was presumably designed with variable cache durations for a reason (not just "forever" and "never"), and changing the URL to a resource only because the resource has been modified seems to go against the spirit of HTTP.

Are "forever" and "never" the only cache durations that you should use in practice? Is this in conflict with other best practices on the web?

In addition to the typical "user with a browser" use case, I would also like to know how these principles apply to REST/hypermedia APIs.

Jakob
  • 2,588
  • 5
  • 27
  • 34
  • My favorite cache header is `Cache-Control: private, max-age=0` which can be combined optionally with `ETag` equal to resource hash or resource version. It makes best results in case of usage Ajax or RESTful API. See [the answer](http://stackoverflow.com/a/9269567/315935) for example. – Oleg Oct 18 '14 at 21:21

4 Answers4

4

Many people would disagree with limiting yourself to "forever" or "never" as you describe it.

For one thing, it ignores the option of allowing caching with always revalidating. In this case, if the client (or proxy) has cached the resource, it sends a conditional HTTP request. If the client/proxy has cached the latest version of the resource, then the server sends a short 304 response rather than the entire resource. If the client's (proxy) copy is out of date, then the server sends the entire resource.

With this scheme, the client will always get an up-to-date version of the resource, and if the resource doesn't change much bandwidth will be saved.

To save even more bandwidth, the client can be instructed to revalidate only when the resource is older than a certain period of time.

And if bad proxies are a problem, the server can specify that only clients and not proxies may cache the resource.

I found this document pretty concisely describes your options for caching. This page is longer but also gives some excellent information.

Craig S. Anderson
  • 6,966
  • 4
  • 33
  • 46
  • If modified since is bad because of latency. – Zan Lynx Oct 24 '14 at 00:10
  • There is a tradeoff between avoiding latency and the browser cache serving stale data. If it the content rarely changes, or serving stale data is ok, then revalidate only once a month or longer. – Craig S. Anderson Oct 24 '14 at 00:17
2

"It depends" really, on your use case, what you are trying to achieve, and your branding proposition.

If all you want to achieve is some bandwidth saving, you could do a total cost breakdown. Serving cost might not amount to much. Browsers are anyway pretty smart at optimizing image hits, for example, so understand your HTTP protocol. Forever, combined with versioned resource url, and url rewrite rules might be a good fit, like your Google engineer suggested.

Resource volatility is another. If you are only serving daily stock charts for example, it could safely be cached for some time but not forever.

Are your computation costs heavy? Are your users sensitive to timeliness? Is data live or fixed? For example, you might be serving airline routes, path of a hurricane, option greeks or a BI report to COO. You might want to have it cached, but the TTL will likely vary by user class, all the way down to never. Forever cannot work for live data but never might be a wrong answer too.

Degree of cooperation between the server and the client may be another factor. For example in a business operations environment where procedures can be distributed and expected to be followed, it might be worthwhile to again look at TTLs.

HTH. I doubt if there is a magical answer.

Dinesh
  • 4,437
  • 5
  • 40
  • 77
0

Idealy, you muste cache until the content changes, if you cannot clear/refresh the cache when content changes for any reason, you need a duration. But indeed, if you can, cache forever or do not cache. No need to refresh if you already know nothing changed.

KyleK
  • 4,643
  • 17
  • 33
0

If you know that the underlying data will be static for any length of time, caching makes sense. We have a web service that exposes data from a database that is populated by a nightly ETL job from an external source. Our RESTful web service only goes to the database when it changes. In our case, we know exactly when the data changes and we invalidate the cache right after the ETL process finishes.

Paul Croarkin
  • 14,496
  • 14
  • 79
  • 118