UpstashRedisCache is the Cache component’s serverless backend. It talks to Upstash Redis over its HTTP REST API — no persistent TCP connection — which makes it a natural fit for edge and serverless runtimes. It implements the same ICache interface as every other backend, so you can develop against the filesystem or a local Redis and switch to Upstash in production without changing a single call site.
Why Upstash
- Serverless-friendly. Connects over HTTP REST, so it works in edge functions and short-lived runtimes where TCP pooling is awkward.
- Same
ICacheinterface.get,set,delete,has,deleteByPrefix, andclear— identical to the filesystem and Redis backends. - Namespaced keys. Every key is prefixed with a namespace (default
cache) so multiple apps can share one Upstash database safely. - Prefix operations.
deleteByPrefix()andclear()use cursor-basedSCANplus pipelined deletes to stay efficient on large keyspaces. - Container-managed. Registered with
@decorator.cache()and resolved from the container.
Installation
UpstashRedisCache ships with @ooneex/cache and depends on the Upstash Redis client.
Environment variables
| Variable | Required | Purpose |
|---|---|---|
CACHE_UPSTASH_REDIS_REST_URL | Yes | Upstash Redis REST URL. Missing throws CacheException (CONFIG_REQUIRED). |
CACHE_UPSTASH_REDIS_REST_TOKEN | Yes | Upstash Redis REST token. Missing throws CacheException (CONFIG_REQUIRED). |
url, token), which take precedence over the environment. Either way they are validated when the cache is constructed, so misconfiguration fails fast.
Options
UpstashRedisCache accepts an options object as its second constructor argument:
| Option | Type | Default | Purpose |
|---|---|---|---|
namespace | string | "cache" | Key prefix; every key is stored as <namespace>:<key>. |
url | string | CACHE_UPSTASH_REDIS_REST_URL | Override the REST URL. |
token | string | CACHE_UPSTASH_REDIS_REST_TOKEN | Override the REST token. |
How it works
Keys are namespaced before they hit Redis:set("user:1", …) with the default namespace writes cache:user:1. Reads, writes, and existence checks map straight onto Upstash commands, while the bulk operations iterate the keyspace with SCAN and delete matches in a pipeline.
| Method | Purpose |
|---|---|
get<T>(key) | Read a value, or undefined if absent. |
set<T>(key, value, ttl?) | Write a value; ttl (seconds) sets an expiry via EX. |
delete(key) | Delete one key; returns whether a key was removed. |
has(key) | Whether a key exists. |
deleteByPrefix(prefix) | SCAN + pipelined delete of <namespace>:<prefix>*; returns the count deleted. |
clear() | SCAN + pipelined delete of every key under the namespace. |
Usage
The API is identical to every other cache backend.Use in the app
In an@ooneex/app application, pass UpstashRedisCache to the cache slot of your App config. The framework registers it and exposes it as the "cache" container constant.
cache key has its response cached automatically — the framework builds the cache key from the route’s cache prefix, HTTP method, URL, and the authenticated user’s id:
CACHE_UPSTASH_REDIS_REST_URL and CACHE_UPSTASH_REDIS_REST_TOKEN in your .env.yml (or environment) so the cache can connect.
Exceptions
UpstashRedisCache throws CacheException on misconfiguration, carrying a machine-readable key.
| Key | When |
|---|---|
CONFIG_REQUIRED | The REST URL or token is missing from both options and the environment. |
Best practices
- Set a TTL for volatile data. Pass
ttl(seconds) onset()so transient values expire instead of accumulating. - Namespace per concern. Use distinct namespaces (sessions, rate counters, query cache) so
clear()anddeleteByPrefix()only touch what you intend. - Use structured key prefixes. Group related keys like
user:123:profilesodeleteByPrefix("user:123:")can invalidate them together. - Keep credentials in the environment. Load the REST URL and token from
.env; never hard-code them. - Develop locally, deploy on Upstash. Use the filesystem or local Redis backend in development and switch to Upstash in production — the
ICachecalls stay identical.