# Execution Caching
The @cache
directive enables to cache the result of a heavy-to-compute operation. The first time the field is resolved, the @cache
directive will save the value in disk or memory (Redis, Memcached), either with an expiry date or not, and from then on whenever querying this field the cached value will be retrieved and the operation will not be performed.
For instance, this query executes the @translate
directive, which does a single connection to the Google Translate API and performs the translation of the posts' titles:
query {
posts(limit:3) {
id
title @translate(from:"en", to:"es")
}
}
Assuming this is an expensive call, we can cache the field's value after the first response. This query achieves that through the @cache
directive, passing a time expiration of 10 seconds (not passing this value, the cache does not expire):
query {
posts(limit:3) {
id
title @translate(from:"en", to:"es") @cache(time:10)
}
}
TIP
Directives in GraphQL are applied in order, so the following queries are different:
title @translate @cache
title @cache @translate
In the 1st case, it executes @translate
and then @cache
, so the translation is being cached; in the 2 case, it executes @cache
and then @translate
, so the caching only stores the value of the title
field and not its translation.
The first time we execute the query, we obtain this response:
The 2nd time, executing the same query within 10 seconds, we obtain the same response, but a log also informs us that the value is coming from the cache:
Tip: How to show logs in the response
Logs are retrieved by passing parameter show_logs=true
to the GraphiQL client, which sets parameter actions[]=show-logs
to the GraphQL endpoint /api/graphql/
Please notice how the log indicates which are the items that have been cached. If we increase field post
's limit
to 6, and run again within 10 seconds, the already-cached 3 items will be retrieved from the cache, and the other 3, which had not been cached yet, will be retrieved fresh through Google Translate:
If we run it again, now all 6 items will be cached:
# Configuration
# Caching adapter
GraphQL by PoP uses Symfony's Cache Component for caching.
By default it stores the cache in the file system, through the Filesystem Cache Adapter, as configured in file services.yaml
from package Component Model:
services:
persistent_cache_item_pool:
class: \Symfony\Component\Cache\Adapter\FilesystemAdapter
public: true
Defining service persistent_cache_item_pool
on another package will override the default adapter. For instance, for improving performance, we can store the cache in memory using Redis (through this adapter) or Memcached (through this adapter).
The full list of adapters is here.