TLDR:
What is the difference between the
Public, max-age=<VALUE>
andmaxage=<VALUE>, s-maxage=<VALUE>
cache-control syntax?
Question:
For one of my projects, I am looking to reduce the server load via the Cache-control
http-header. This project is hosted as a serverless function on Vercel and calls GitHub's GraphQL API on the backend to retrieve GitHub user information. Both the Vercel API and GitHub API are rate limited, so I am looking for the best header to prevent these limits from being hit. To achieve this, I am currently using the following Cache-control header:
public, max-age=14400, stale-while-revalidate=86400
According to the Mozilla documentation, this header should keep both the private browser cache and server cache fresh for 4 hours, while the stale cache can be reused for 1 day while it revalidates on the server. Furthermore, since I am not using an authentication header, I should be able even to remove the Public
keyword.
The Vercel cache documentation, however, recommends the following header:
maxage=0, s-maxage=14400, stale-while-revalidate=86400
Based on the Vercel documentation and this Stack Overflow question, I, therefore, think the following header is best suited for reducing both the Vercel and GitHub load:
maxage=14400, s-maxage=7200, stale-while-revalidate=86400
To my understanding, with this header, the cache will be fresh for 4 hours for individual users while the Vercel server refreshes the cache every 2 hours, and a stale cache can be reused for 1 day while it revalidates on the server.
As I am uncertain about the difference between the Public, max-age=<VALUE>
and maxage=<VALUE>, s-maxage=<VALUE>
syntax, I quickly wanted to double-check my understanding.
According to the Mozilla documentation, these two syntaxes should result in the same behaviour if the <VALUE>
is equal between maxage
and s-maxage
properties. However, the Symfony documentation states that the s-maxage
flag prohibits a cache from using a stale response in stale-if-error scenarios. My question is, therefore: What is the exact difference between these two syntaxes, and which one would you recommend for reducing the load on both the Vercel and GitHub api?
The Vercel-recommended cache headers are well-suited to minimizing the number of API calls:
Cache-Control: max-age=0, s-maxage=N
The s-maxage
is used to control caching by the Vercel Edge Network, allowing it to serve cached responses rather than call the serverless function. As far as I know it does not have rate limits of its own.
Of course, you probably have other caching goals besides just reducing API calls. So you might want to use max-age
as well to allow browser caching to reduce latency for your users.
It's also a good idea to use stale-while-revalidate
, but note that this is just a mechanism to reduce latency. The revalidation still happens, so it won't have an effect on the number of API calls.
As for public
, it means "that any cache MAY store the response, even if the response would normally be non-cacheable or cacheable only within a private cache". If your response is already cacheable by a public cache then this directive won't have any effect.