# Redis Cache

By default, Quarkus Cache uses Caffeine as backend. It’s possible to use Redis instead.

| This technology is considered preview. In preview, backward compatibility and presence in the ecosystem is not guaranteed. Specific improvements might require changing configuration or APIs, and plans to become stable are under way. Feedback is welcome on our mailing list or as issues in our GitHub issue tracker. For a full list of possible statuses, check our FAQ entry.

## Redis as cache backend

When using Redis as the backend for Quarkus cache, each cached item will be stored in Redis:

- The backend uses the <default> Redis client (if not configured otherwise), so make sure it’s configured (or use the Redis Dev Service)

- the Redis key is built as follows: `cache:{cache-name}:{cache-key}`, where `cache-key` is the key the application uses and `cache:{cache-name}` the prefix.

- the value is encoded to JSON if needed

## Use the Redis backend

First, you need to add the `quarkus-redis-cache` extension to your project:

pom.xml

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-redis-cache</artifactId>
    </dependency>

build.gradle

    implementation("io.quarkus:quarkus-redis-cache")

Then, use the `@CacheResult` and others cache annotations as explained in the Quarkus Cache guide:

    @GET
    @Path("/{keyElement1}/{keyElement2}/{keyElement3}")
    @CacheResult(cacheName = "expensiveResourceCache")
    public ExpensiveResponse getExpensiveResponse(@PathParam("keyElement1") @CacheKey String keyElement1,
            @PathParam("keyElement2") @CacheKey String keyElement2, @PathParam("keyElement3") @CacheKey String keyElement3,
            @QueryParam("foo") String foo) {
        invocations.incrementAndGet();
        ExpensiveResponse response = new ExpensiveResponse();
        response.setResult(keyElement1 + " " + keyElement2 + " " + keyElement3 + " too!");
        return response;
    }

    @POST
    @CacheInvalidateAll(cacheName = "expensiveResourceCache")
    public void invalidateAll() {

    }

## Configure the Redis backend

The Redis backend uses the `<default>` Redis client. See the Redis reference to configure the access to Redis.

| In dev mode, you can use the Redis Dev Service.

If you want to use another Redis for your cache, configure the `client-name` as follows:

    quarkus.cache.redis.client-name=my-redis-for-cache

When writing to Redis or reading from Redis, Quarkus needs to know the type. Indeed, the objects need to be serialized and deserialized. For that purpose, you may need to configure type (class names) of the key and value you want to cache. At build time, Quarkus tries to deduce the types from the application code, but that decision can be overridden using:

    # Default configuration
    quarkus.cache.redis.key-type=java.lang.String
    quarkus.cache.redis.value-type=org.acme.Person

    # Configuration for `expensiveResourceCache`
    quarkus.cache.redis.expensiveResourceCache.key-type=java.lang.String
    quarkus.cache.redis.expensiveResourceCache.value-type=org.acme.Supes

You can also configure the time to live of the cached entries:

    # Default configuration
    quarkus.cache.redis.expire-after-write=10s

    # Configuration for `expensiveResourceCache`
    quarkus.cache.redis.expensiveResourceCache.expire-after-write=1h

If the `expire-after-write` is not configured, the entry won’t be evicted. You would need to invalidate the values using the `@CacheInvalidateAll` or `@CacheInvalidate` annotations.

The following table lists the supported properties:

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property | Type | Default
--- | --- | ---
`quarkus.cache.redis.client-name` The name of the named Redis client to be used for communicating with Redis. If not set, use the default Redis client. Environment variable: `QUARKUS_CACHE_REDIS_CLIENT_NAME` | string |
`quarkus.cache.redis.value-type` The default type of the value stored in the cache. Environment variable: `QUARKUS_CACHE_REDIS_VALUE_TYPE` | string |
`quarkus.cache.redis.key-type` The key type, `String` by default. Environment variable: `QUARKUS_CACHE_REDIS_KEY_TYPE` | string |
`quarkus.cache.redis.expire-after-write` Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after the entry’s creation, or the most recent replacement of its value. Environment variable: `QUARKUS_CACHE_REDIS_EXPIRE_AFTER_WRITE` | Duration |
`quarkus.cache.redis.expire-after-access` Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after the last access of its value. Environment variable: `QUARKUS_CACHE_REDIS_EXPIRE_AFTER_ACCESS` | Duration |
`quarkus.cache.redis.prefix` The key prefix allowing to identify the keys belonging to the cache. If not set, the value "`cache:{cache-name`}" will be used. The variable "`{cache-name`}" is resolved from the value set in the cache annotations. Environment variable: `QUARKUS_CACHE_REDIS_PREFIX` | string |
`quarkus.cache.redis.use-optimistic-locking` Whether the access to the cache should be using optimistic locking. See Redis Optimistic Locking for details. Default is `false`. Environment variable: `QUARKUS_CACHE_REDIS_USE_OPTIMISTIC_LOCKING` | boolean |
`quarkus.cache.redis.invalidation-scan-size` If set, the `SCAN` command (used to implement invalidation) will have the `COUNT` argument with given value. If not set (default), no `COUNT` argument is present. Environment variable: `QUARKUS_CACHE_REDIS_INVALIDATION_SCAN_SIZE` | int |
Additional configuration applied to a specific Redis cache (highest precedence) | Type | Default
`quarkus.cache.redis."cache-name".value-type` The default type of the value stored in the cache. Environment variable: `QUARKUS_CACHE_REDIS__CACHE_NAME__VALUE_TYPE` | string |
`quarkus.cache.redis."cache-name".key-type` The key type, `String` by default. Environment variable: `QUARKUS_CACHE_REDIS__CACHE_NAME__KEY_TYPE` | string |
`quarkus.cache.redis."cache-name".expire-after-write` Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after the entry’s creation, or the most recent replacement of its value. Environment variable: `QUARKUS_CACHE_REDIS__CACHE_NAME__EXPIRE_AFTER_WRITE` | Duration |
`quarkus.cache.redis."cache-name".expire-after-access` Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after the last access of its value. Environment variable: `QUARKUS_CACHE_REDIS__CACHE_NAME__EXPIRE_AFTER_ACCESS` | Duration |
`quarkus.cache.redis."cache-name".prefix` The key prefix allowing to identify the keys belonging to the cache. If not set, the value "`cache:{cache-name`}" will be used. The variable "`{cache-name`}" is resolved from the value set in the cache annotations. Environment variable: `QUARKUS_CACHE_REDIS__CACHE_NAME__PREFIX` | string |
`quarkus.cache.redis."cache-name".use-optimistic-locking` Whether the access to the cache should be using optimistic locking. See Redis Optimistic Locking for details. Default is `false`. Environment variable: `QUARKUS_CACHE_REDIS__CACHE_NAME__USE_OPTIMISTIC_LOCKING` | boolean |
`quarkus.cache.redis."cache-name".invalidation-scan-size` If set, the `SCAN` command (used to implement invalidation) will have the `COUNT` argument with given value. If not set (default), no `COUNT` argument is present. Environment variable: `QUARKUS_CACHE_REDIS__CACHE_NAME__INVALIDATION_SCAN_SIZE` | int |

| About the Duration format To write duration values, use the standard `java.time.Duration` format. See the Duration#parse() Java API documentation for more information. You can also use a simplified format, starting with a number: If the value is only a number, it represents time in seconds. If the value is a number followed by `ms`, it represents time in milliseconds. In other cases, the simplified format is translated to the `java.time.Duration` format for parsing: If the value is a number followed by `h`, `m`, or `s`, it is prefixed with `PT`. If the value is a number followed by `d`, it is prefixed with `P`.

## Configure the Redis key

By default, the Redis backend stores the entry using the following keys pattern: `cache:{cache-name}:{cache-key}`, where `cache-key` is the key the application uses and `cache:{cache-name}` the prefix. The variable `{cache-name}` is resolved from the value set in the cache annotations. So, you can find all the entries for a single cache using the Redis `KEYS` command: `KEYS cache:{cache-name}:*`

The prefix can be configured by using the `prefix` property:

    # Default configuration
    quarkus.cache.redis.prefix=my-cache

    # Configuration for `expensiveResourceCache`
    quarkus.cache.redis.expensiveResourceCache.prefix=my-expensive-cache

In these cases, you can find all the keys managed by the default cache using `KEYS my-cache:*`, and all the keys managed by the `expensiveResourceCache` cache using: `KEYS my-expensive-cache:*`.

    # Default configuration
    # The variable "{cache-name}" is resolved from the value set in the cache annotations.
    quarkus.cache.redis.prefix=my-cache-{cache-name}

In this latest example, you can find all the keys managed by the default cache using `KEYS my-cache-{cache-name}:*`.

## Enable optimistic locking

The access to the cache can be direct or use optimistic locking. By default, optimistic locking is disabled.

You can enable optimistic locking using:

    # Default configuration
    quarkus.cache.redis.use-optimistic-locking=true

    # Configuration for `expensiveResourceCache`
    quarkus.cache.redis.expensiveResourceCache.use-optimistic-locking=true

When used, the key is watched and the SET command is executed in a transaction (`MULTI/EXEC`).