Skip to content
Specific Docs
Esc
↑↓navigate↵open⌘Jpreview
On this page

Redis

Managed Redis-compatible caching backed by Valkey: one block in specific.hcl, a local instance during specific dev, and a connection URL your existing Redis client already understands.

Managed Redis-compatible cache instances, backed by Valkey, the BSD-3-Clause open-source fork of Redis 7.2. Valkey speaks the Redis wire protocol, so any Redis client works unchanged: ioredis, node-redis, redis-py, go-redis, redis-cli.

service "api" {
  build   = build.api
  command = "./api"

  endpoint {
    public = true
  }

  env = {
    REDIS_URL = redis.cache.url
  }
}

redis "cache" {}

One block is one instance. Declare several blocks if you want separate instances, for example one for caching and one for rate limiting, and reference each by name.

Connection attributes

Attribute Description
url Full connection string, in the form redis://:password@host:port.
host Hostname of the instance.
port Port, 6379 in production and a locally allocated port during specific dev.
password Password for AUTH.

Most clients take the URL directly:

import Redis from "ioredis";

const redis = new Redis(process.env.REDIS_URL!);
await redis.set("greeting", "hello", "EX", 60);
import os, redis

r = redis.from_url(os.environ["REDIS_URL"])
r.set("greeting", "hello", ex=60)

The URL uses the redis:// scheme (plain TCP), not rediss://. In production the instance is only reachable from services inside the same environment, never from the public internet.

Local development and production

During specific dev, a local Valkey server starts automatically on a free port, and the redis.* references resolve to it. Nothing to install, nothing to configure.

In production, specific deploy provisions a dedicated instance per redis block in each environment, generates a password, and injects the same references into your services. Preview environments get their own instances too.

What it is for

Redis on Specific is a cache, not a database. Instances run without persistence, locally and in production: a restart starts empty. Production instances have a fixed memory budget and evict the least recently used keys when it is full.

Good fits:

  • Caching query results, rendered fragments, and API responses with a TTL.
  • Sessions and short-lived tokens that can be re-issued if lost.
  • Rate limiting and counters.
  • Pub/sub between services in the same environment.

For work that must survive a restart, such as background jobs, use a Temporal workflow engine instead of a Redis-backed queue, and keep durable data in Postgres.

Common questions

Which Redis commands are supported?

Valkey 8 supports the Redis 7.2 command set, including streams, pub/sub, Lua scripting, and the standard data types. Commands added to Redis after the fork, and Redis Stack modules such as RedisJSON and RediSearch, are not available.

Can I use BullMQ or another Redis-based queue?

It connects and runs, but without persistence, queued jobs are lost whenever the instance restarts. Use it only for work you can afford to drop, and prefer Temporal for anything that has to complete.

How do I inspect the cache?

Locally, connect with redis-cli -u "$REDIS_URL" using the URL from the service’s environment, or read the values from your application. In production there is no direct access from outside the environment; add a debug endpoint to a service if you need to look inside.

Does the data survive a deploy?

No. Each deploy can restart the instance, and there are no snapshots. Treat every key as something your app can recompute.

Was this page helpful?