Upsun User Documentation

Redis (Object cache)

Upsun Beta access

Test and provide feedback for our newest offering - Upsun!

You can register for the Beta by clicking here and completing the form.

Sign up for Beta access

Redis is a multi-model database that allows you to store data in memory for high-performance data retrieval and key-value storage. Upsun supports two different Redis configurations:

  • Persistent: to set up fast persistent storage for your application
  • Ephemeral: to set up a non-persistent cache for your application

Supported versions Anchor to this heading

You can select the major and minor version.

Patch versions are applied periodically for bug fixes and the like. When you deploy your app, you always get the latest available patches.

  • 7.2
  • 7.0
  • 6.2

Deprecated versions Anchor to this heading

The following versions are deprecated. They’re available, but they aren’t receiving security updates from upstream and aren’t guaranteed to work. They’ll be removed in the future, so migrate to one of the supported versions.

  • 6.0
  • 5.0
  • 4.0
  • 3.2
  • 3.0
  • 2.8

Note that versions 3.0 and higher support up to 64 different databases per instance of the service, while Redis 2.8 only supports a single database.

Service types Anchor to this heading

Depending on your needs, you can set up Redis as persistent or ephemeral.

Persistent Redis Anchor to this heading

By default, Redis is an ephemeral service that stores data in memory. This allows for fast data retrieval, but also means data can be lost when a container is moved or shut down.

To solve this issue, configure your Redis service as persistent. Persistent Redis stores data on a disk, restoring it if the container restarts.

To switch from persistent to ephemeral Redis, set up a new service with a different name.

Usage example Anchor to this heading

1. Configure the service Anchor to this heading

To define the service, use the redis-persistent endpoint:

.upsun/config.yaml
services:
    # The name of the service container. Must be unique within a project.
    <SERVICE_NAME>:
        type: redis-persistent:<VERSION>

Note that changing the name of the service replaces it with a brand new service and all existing data is lost. Back up your data before changing the service.

2. Add the relationship Anchor to this heading

To define the relationship, use the redis endpoint :

.upsun/config.yaml
applications:
    # The name of the app container. Must be unique within a project.
    <APP_NAME>:
        # Relationships enable access from this app to a given service.
        relationships:
            <RELATIONSHIP_NAME>: "<SERVICE_NAME>:redis"

services:
    # The name of the service container. Must be unique within a project.
    <SERVICE_NAME>:
        type: redis-persistent:<VERSION>

You can define <SERVICE_NAME> and <RELATIONSHIP_NAME> as you like, but it’s best if they’re distinct. With this definition, the application container now has access to the service via the relationship <RELATIONSHIP_NAME>. For PHP, enable the extension for the service:

.upsun/config.yaml
applications:
    # The name of the app container. Must be unique within a project.
    <APP_NAME>:
        # PHP extensions.
        runtime:
            extensions:
                - redis
        # Relationships enable access from this app to a given service.
        relationships:
            <RELATIONSHIP_NAME>: "<SERVICE_NAME>:redis"

services:
    # The name of the service container. Must be unique within a project.
    <SERVICE_NAME>:
        type: redis-persistent:<VERSION>

Configuration example Anchor to this heading

Service and app configuration Anchor to this heading

.upsun/config.yaml
applications:
    # The name of the app container. Must be unique within a project.
    myapp:
        # Relationships enable access from this app to a given service.
        relationships:
            rediscache: "cacheredis:redis"

services:
    # The name of the service container. Must be unique within a project.
    cacheredis:
        type: redis-persistent:7.0

Use in app Anchor to this heading

To use the configured service in your app, add a configuration file similar to the following to your project.

.upsun/config.yaml
applications:
    # The name of the app container. Must be unique within a project.
    myapp:
        # The location of the application's code.
        source:
            root: "myapp"
        # Other options...
        
        # Relationships enable an app container's access to a service.
        relationships:
            rediscache: "cacheredis:redis"
services:
    # The name of the service container. Must be unique within a project.
    cacheredis:
        type: redis-persistent:7.2

This configuration defines a single application myapp, whose source code exists in the directory <PROJECT_ROOT>/myapp, and has been provided access to the service (cacheredis) via the relationship rediscache.

From this, myapp can retrieve access credentials to the service through the environment variable PLATFORM_RELATIONSHIPS. That variable is a base64-encoded JSON object, but can be decoded at runtime (using the built-in tool jq) to provide more accessible environment variables to use within the application itself:

myapp/.environment
# Decode the built-in credentials object variable.
export RELATIONSHIPS_JSON=$(echo $PLATFORM_RELATIONSHIPS | base64 --decode)

# Set environment variables for individual credentials.
export CACHE_HOST="$(echo $RELATIONSHIPS_JSON | jq -r '.rediscache[0].host')"
export CACHE_PORT="$(echo $RELATIONSHIPS_JSON | jq -r '.rediscache[0].port')"
export CACHE_PASSWORD="$(echo $RELATIONSHIPS_JSON | jq -r '.rediscache[0].password')"
export CACHE_SCHEME="$(echo $RELATIONSHIPS_JSON | jq -r '.rediscache[0].scheme')"

# Surface a Redis connection string for use in app.
export REDIS_URL="${CACHE_SCHEME}://${CACHE_PASSWORD}@${CACHE_HOST}:${CACHE_PORT}"

The above file — .environment in the myapp directory — is automatically sourced by Upsun into the runtime environment, so that the variable REDIS_URL can be used within the application to connect to the service.

Note that REDIS_URL, and all Upsun-provided environment variables like PLATFORM_RELATIONSHIPS, are environment-dependent. Unlike the build produced for a given commit, they can’t be reused across environments and only allow your app to connect to a single service instance on a single environment.

A file very similar to this is generated automatically for your when using the upsun ify command to migrate a codebase to Upsun.

Ephemeral Redis Anchor to this heading

By default, Redis is an ephemeral service that serves as a non-persistent cache. Ephemeral Redis stores data only in memory and requires no disk space. When the service reaches its memory limit, it triggers a cache cleanup. To customize those cache cleanups, set up an eviction policy.

Make sure your app doesn’t rely on ephemeral Redis for persistent storage as it can cause issues. For example, if a container is moved during region maintenance, the deploy and post_deploy hooks don’t run and an app that treats the cache as permanent shows errors.

To prevent data from getting lost when a container is moved or shut down, you can use the persistent Redis configuration. Persistent Redis provides a cache with persistent storage.

Usage example Anchor to this heading

1. Configure the service Anchor to this heading

To define the service, use the redis endpoint:

.upsun/config.yaml
services:
    # The name of the service container. Must be unique within a project.
    <SERVICE_NAME>:
        type: redis:<VERSION>

Note that changing the name of the service replaces it with a brand new service and all existing data is lost. Back up your data before changing the service.

2. Add the relationship Anchor to this heading

To define the relationship, use the redis endpoint :

.upsun/config.yaml
applications:
    # The name of the app container. Must be unique within a project.
    <APP_NAME>:
        # Relationships enable access from this app to a given service.
        relationships:
            <RELATIONSHIP_NAME>: "<SERVICE_NAME>:redis"

services:
    # The name of the service container. Must be unique within a project.
    <SERVICE_NAME>:
        type: redis:<VERSION>

You can define <SERVICE_NAME> and <RELATIONSHIP_NAME> as you like, but it’s best if they’re distinct. With this definition, the application container now has access to the service via the relationship <RELATIONSHIP_NAME>. For PHP, enable the extension for the service:

.upsun/config.yaml
applications:
    # The name of the app container. Must be unique within a project.
    <APP_NAME>:
        # PHP extensions.
        runtime:
            extensions:
                - redis
        # Relationships enable access from this app to a given service.
        relationships:
            <RELATIONSHIP_NAME>: "<SERVICE_NAME>:redis"

services:
    # The name of the service container. Must be unique within a project.
    <SERVICE_NAME>:
        type: redis:<VERSION>

Configuration example Anchor to this heading

Service and app configuration Anchor to this heading

.upsun/config.yaml
applications:
    # The name of the app container. Must be unique within a project.
    myapp:
        # Relationships enable access from this app to a given service.
        relationships:
            rediscache: "cacheredis:redis"

services:
    # The name of the service container. Must be unique within a project.
    cacheredis:
        type: redis:7.0

Use in app Anchor to this heading

To use the configured service in your app, add a configuration file similar to the following to your project.

.upsun/config.yaml
applications:
    # The name of the app container. Must be unique within a project.
    myapp:
        # The location of the application's code.
        source:
            root: "myapp"
        # Other options...
        
        # Relationships enable an app container's access to a service.
        relationships:
            rediscache: "cacheredis:redis"
services:
    # The name of the service container. Must be unique within a project.
    cacheredis:
        type: redis:7.2

This configuration defines a single application myapp, whose source code exists in the directory <PROJECT_ROOT>/myapp, and has been provided access to the service (cacheredis) via the relationship rediscache.

From this, myapp can retrieve access credentials to the service through the environment variable PLATFORM_RELATIONSHIPS. That variable is a base64-encoded JSON object, but can be decoded at runtime (using the built-in tool jq) to provide more accessible environment variables to use within the application itself:

myapp/.environment
# Decode the built-in credentials object variable.
export RELATIONSHIPS_JSON=$(echo $PLATFORM_RELATIONSHIPS | base64 --decode)

# Set environment variables for individual credentials.
export CACHE_HOST="$(echo $RELATIONSHIPS_JSON | jq -r '.rediscache[0].host')"
export CACHE_PORT="$(echo $RELATIONSHIPS_JSON | jq -r '.rediscache[0].port')"
export CACHE_PASSWORD="$(echo $RELATIONSHIPS_JSON | jq -r '.rediscache[0].password')"
export CACHE_SCHEME="$(echo $RELATIONSHIPS_JSON | jq -r '.rediscache[0].scheme')"

# Surface a Redis connection string for use in app.
export REDIS_URL="${CACHE_SCHEME}://${CACHE_PASSWORD}@${CACHE_HOST}:${CACHE_PORT}"

The above file — .environment in the myapp directory — is automatically sourced by Upsun into the runtime environment, so that the variable REDIS_URL can be used within the application to connect to the service.

Note that REDIS_URL, and all Upsun-provided environment variables like PLATFORM_RELATIONSHIPS, are environment-dependent. Unlike the build produced for a given commit, they can’t be reused across environments and only allow your app to connect to a single service instance on a single environment.

A file very similar to this is generated automatically for your when using the upsun ify command to migrate a codebase to Upsun.

Multiple databases Anchor to this heading

Redis 3.0 and above support up to 64 databases. But you can’t set up different access rights to each database. When you set up a relationship connection, access to all of the databases is automatically granted.

The way to access a particular database depends on the client library you’re using:

Use the Redis select command:

<?php
$redis = new Redis();
$redis->connect(getenv('CACHE_HOST'), getenv('CACHE_PORT'));

$redis->select(0);       // switch to DB 0
$redis->set('x', '42');  // write 42 to x
$redis->move('x', 1);    // move to DB 1
$redis->select(1);       // switch to DB 1
$redis->get('x');        // returns 42

To manage thread safety, the Python library suggests using separate client instances for each database:

import os
from redis import Redis

database0 = Redis(host=os.getenv('CACHE_HOST'), port=os.getenv('CACHE_PORT'), db=0)
database1 = Redis(host=os.getenv('CACHE_HOST'), port=os.getenv('CACHE_PORT'), db=1)

Use the Redis select command:

const redis = require('redis');

const client = redis.createClient(process.env.CACHE_PORT, process.env.CACHE_HOST);

await client.SELECT(0);                  // switch to DB 0
await client.set('x', '42');             // write 42 to x
await client.MOVE('x', 1);               // move to DB 1
await client.SELECT(1);                  // switch to DB 1
const value = await client.get('x');     // returns 42

Relationship reference Anchor to this heading

Example information available through the PLATFORM_RELATIONSHIPS environment variable or by running upsun relationships.

Note that the information about the relationship can change when an app is redeployed or restarted or the relationship is changed. So your apps should only rely on the PLATFORM_RELATIONSHIPS environment variable directly rather than hard coding any values.

{
    "username": null,
    "scheme": "redis",
    "service": "redis6",
    "fragment": null,
    "ip": "169.254.22.75",
    "hostname": "7mnenhdiz7ecraovljrba6pmiy.redis6.service._.eu-3.upsunapp.com",
    "port": 6379,
    "cluster": "rjify4yjcwxaa-master-7rqtwti",
    "host": "redis.internal",
    "rel": "redis",
    "path": null,
    "query": [],
    "password": null,
    "type": "redis:7.2",
    "public": false,
    "host_mapped": false
}

The format of the relationship is identical whether your Redis service is ephemeral or persistent.

Eviction policy Anchor to this heading

When ephemeral Redis reaches its memory limit, it triggers a cache cleanup. To customize those cache cleanups, set up an eviction policy such as the following:

.upsun/config.yaml
services:
    # The name of the service container. Must be unique within a project.
    cache:
        type: "redis:7.2"
        configuration:
            maxmemory_policy: allkeys-lfu

The following table presents the possible values:

Value Policy description
allkeys-lru Removes the oldest cache items first. This is the default policy when maxmemory_policy isn’t set.
noeviction New items aren’t saved when the memory limit is reached.
allkeys-lfu Removes least frequently used cache items first.
volatile-lru Removes least recently used cache items with the expire field set to true.
volatile-lfu Removes least frequently used cache items with the expire field set to true.
allkeys-random Randomly removes cache items to make room for new data.
volatile-random Randomly removes cache items with the expire field set to true.
volatile-ttl Removes cache items with the expire field set to true and the shortest remaining time-to -live value.

For more information on the different policies, see the official Redis documentation.

Access your Redis service through the Redis CLI Anchor to this heading

After you’ve configured your Redis service, you can access it using the Redis CLI.

Retrieve the hostname and port you can connect to through the PLATFORM_RELATIONSHIPS environment variable. To do so, run the upsun relationships command.

After you’ve retrieved the hostname and port, open an SSH session. To access your Redis service, run the following command:

redis-cli -h HOSTNAME -p PORT

Note that the CONFIG GET and CONFIG SET admin commands might be restricted on your project.

redis-cli -h HOSTNAME -p PORT info

Use Redis as a handler for PHP sessions Anchor to this heading

A PHP session allows you to store different data for each user through a unique session ID. By default, PHP handles sessions using files. But you can use Redis as a session handler, which means Redis stores and retrieves the data saved into sessions.

To set up Redis as your session handler, add a configuration similar to the following:

.upsun/config.yaml
applications:
    # The name of the app container. Must be unique within a project.
    myapp:
        type: "php:8.3"
        
        relationships:
            sessionstorage: "data:redis"
        
        variables:
            php:
                session.save_handler: redis
                session.save_path: "tcp://HOSTNAME:PORT"
        
        web:
            locations:
                '/':
                    root: 'web'
                    passthru: '/index.php'

services:
    # The name of the service container. Must be unique within a project.
    data:
        type: "redis-persistent:7.2"

Is this page helpful?