# HTTP Caching
HTTP caching works only when invoking GraphQL via GET through a persisted query (against a custom endpoint), or when sending the query using PQL.
Why is HTTP caching not supported otherwise?
HTTP caching relies on the URL being a unique identifier of the request. GraphQL normally submits all queries against the same endpoint, and passing the query in the body of the request through a POST operation, instead of a GET. Then, GraphQL queries cannot be distinguished from each other, and hence cannot be cached.
Persisted queries invoked through a custom endpoint, and PQL, do not have this issue because they are URL-based, so executing 2 queries will be done through 2 different URLs, and these can be uniquely identified and cached.
The response will contain a
Cache-Control header with the
max-age value set at the time (in seconds) to cache the request, or
no-store if the request must not be cached. Each field in the schema can configure its own
max-age value, and the response's
max-age is calculated as the lowest
max-age among all requested fields (including composable fields).
# How it works
@cacheControl is added to the directive pipeline for all fields. This directive is configured a
max-age value for each field, and adds a
Cache-Control header to the response with the lowest
max-age value from all the requested fields in the query, or
no-store if any field has
Click on the links below, and inspect the response headers using Chrome or Firefox's developer tools' Network tab to see the
Operators have a
max-age of 1 year:
/?query= echo(Hello world!)
By default, fields have a
max-age of 1 hour:
/?query= echo(Hello world!)| posts. title
Composed fields are also taken into account when computing the lowest
"time" field is not to be cached (max-age: 0):
# How to not cache a response
If the response is cacheable, but we need to fetch a fresh response, we can avoid the response from being cached through these 2 ways:
- Add field
"time"to the query:
/?query= time| echo(Hello world!)| posts. title
- Override the default
maxAgeconfiguration for a field, by adding argument
maxAge: 0to directive
@cacheControlon any field in the query:
/?query= echo(Hello world!)| posts. title<cacheControl(maxAge:0)>