Skip to main content
A Node.js application on Sevalla reaches a Redis or Valkey database over an internal connection: the connection adds the database’s host, port and password to the application as environment variables, and ioredis connects with them over the private network. This guide caches a slow response in Redis from an Express application. Because every instance and process of the application shares the database, the cache, sessions and queues you keep there work with more than one instance.

At a glance

What this guide adds to the Express application:

Environment variables

The Express application’s own variables are in its table. The internal connection also adds REDIS_URL, which redis.js doesn’t read.

Before you begin

  • An Express application deployed on Sevalla, as in Deploy Express.
  • Node.js 20 or later in the application, which ioredis 6 needs. The Express guide pins Node.js 24.

Create a Redis database

1

Create the database

In the sidebar, click Databases, then click Create database. Under Database, choose Redis or Valkey and the version. Enter storefront-redis as the Display name, choose the same Data center as the application and a Size, then click Create database. See Create a database for every field.
2

Connect it to the application

In the sidebar, click Applications, then click the application. Click the Networking tab. Under Connected services, click Add internal connection. Choose storefront-redis as the Service, turn on Add environment variables to the application, and click Add internal connection. Only services in the application’s location are listed.
The connection adds four variables to the application, which apply at the next deployment: Redis and Valkey databases have a password but no username, and clients use logical database 0. See Connect an application.

Install ioredis

Create the client

Create one client for the whole application, from the separate variables:
redis.js
The separate variables work for both engines, and so does new Redis(process.env.REDIS_URL): REDIS_URL starts with redis:// for Redis and Valkey. A Valkey REDIS_URL added before Oct 30, 2026 starts with valkey://, which ioredis doesn’t parse as a URL. ioredis reconnects on its own when the connection drops, and queues commands until it’s back.

Cache a slow response

Add a route to server.js that keeps its result in Redis for 60 seconds:
server.js
EX 60 makes Redis delete the key after 60 seconds, so the next request loads fresh data. Delete the key with redis.del("products") when the data changes. The SIGTERM handler runs on every deployment: Ingot’s image starts the server under tini, which passes the stop signal on to Node.js.

Deploy and verify

Commit and push the changes, package-lock.json included: Ingot installs ioredis from it with npm ci and starts the server from the start script as before. With auto-deploy on, the push starts a deployment; otherwise, start one with Deploy now on the application’s Overview tab. The deployment also gives the application the variables the internal connection added. When the deployment’s status changes to Deployed:
  1. Request the route twice. Use your application’s domain instead of storefront-x7k2m.sevalla.app:
    The first response has the header x-cache: miss and takes about a second. The second has x-cache: hit and returns at once.
  2. On the database’s Redis studio tab, the products key appears with its value until it expires. See Database studio.
If the requests fail, read the application’s runtime logs:

Use Redis from other processes

Environment variables belong to the application, so its background workers and cron jobs get the same REDIS_* variables as the web process. Import the same redis.js in a worker to process a queue, or store sessions in Redis with your framework’s Redis session store so that a visitor stays signed in on every instance.

Deploy with the API

This sequence adds the Redis database of this guide to the application from Deploy Express through the Sevalla API, so an agent or a script can run it as is. APP_ID is that application, and the changes on this page are pushed to its branch. Each step names the operation, shows the curl command, and gives the matching CLI command and MCP server tool. You need an API key with the Company developer role in the SEVALLA_API_KEY environment variable (the CLI reads the same key from SEVALLA_API_TOKEN), and curl, jq and openssl. A call that fails returns status and message instead of the resource, and jq -r .id prints null: stop and read the message.
1

Look up the location and the database size

Get application (getApplicationV3) returns the application’s location in cluster_id; the database must be in the same one. List database resource types (listDatabaseResourceTypesV3) returns the database sizes; DB1 is the smallest.
CLI: sevalla apps get "$APP_ID" and sevalla resources db-types. MCP: get_application and get_platform_options.
2

Create the database

Create database (createDatabaseV3) starts creating a Redis 8.6 database with a password you generate. List database versions (listDatabaseVersionsV3) lists the versions of a location; a Valkey database works the same way with "type": "valkey".
CLI: sevalla databases create --name storefront-redis --type redis --db-version 8.6 --cluster "$CLUSTER_ID" --resource-type "$DB_SIZE_ID" --db-name storefront --db-password "$DB_PASSWORD". MCP: create_database, which generates a password and doesn’t return it; set one you know afterwards with sevalla_api_update, resetDatabasePasswordV3 and {"new_password": "..."}.
3

Connect the database

Create internal connection (createDatabaseInternalConnectionV3) connects the database to the application over the private network. Unlike the dashboard, it adds no environment variables: a later step adds them.
CLI: sevalla databases connections internal-create "$DB_ID" --target-id "$APP_ID" --target-type app. MCP: sevalla_api_create with createDatabaseInternalConnectionV3.
4

Read the database details

Get database (getDatabaseV3) returns the database’s internal hostname and port. The loop waits until its status is ready.
CLI: sevalla databases get "$DB_ID" --json. MCP: get_database.
5

Add the environment variables

Create environment variable (createEnvironmentVariableV3) adds one variable per call. add_var sends each one as available during runtime only. These are the variables the dashboard’s internal connection adds, except REDIS_URL, which the code doesn’t read:
CLI: sevalla apps env-vars create "$APP_ID" --key REDIS_HOST --value "$(jq -r .internal_hostname <<< "$DB")", once per variable; the CLI makes each one available during the build too. MCP: set_environment_variables with the three variables in one call, each with runtime true and buildtime false.
6

Deploy

Trigger deployment (triggerDeploymentV3) builds the latest commit of the branch and rolls it out.
CLI: sevalla apps deployments trigger "$APP_ID". MCP: trigger_deployment.
7

Wait for the deployment

Get deployment (getDeploymentV3) returns the deployment’s status: waiting, then inProgress, then success or failed. The loop polls every 15 seconds for up to 30 minutes and keeps polling through a failed request.
CLI: sevalla apps deployments get "$DEPLOYMENT_ID" --app-id "$APP_ID". MCP: get_deployment.
8

Check the deployment

List application domains (listApplicationDomainsV3) returns the application’s domain. Request the route twice and read the X-Cache header:
The first request misses the cache and the second hits it:
CLI: sevalla apps domains list --app-id "$APP_ID". MCP: get_application.