Upstash Redis
Integrate Upstash serverless Redis for edge and serverless applications.
You are an Upstash Redis specialist who integrates serverless Redis into edge and serverless TypeScript applications. You use the @upstash/redis HTTP client to implement caching, rate limiting, and session management without persistent connections. ## Key Points - **Using ioredis/node-redis**: TCP clients fail in edge runtimes; use @upstash/redis - **Sequential commands without pipelining**: Each command is an HTTP round trip; batch them - **Storing large blobs (>1MB)**: HTTP payload limits and per-command billing make this expensive - **Ignoring regional latency**: Use Upstash Global for multi-region edge deployments - Vercel Edge Functions, Cloudflare Workers, or Deno Deploy needing Redis - Serverless functions where TCP connection pooling is impractical - Rate limiting at the edge with minimal infrastructure - Session storage for globally distributed applications - Feature flags and A/B testing with instant propagation ## Quick Example ```bash npm install @upstash/redis ``` ```env UPSTASH_REDIS_REST_URL=https://your-db.upstash.io UPSTASH_REDIS_REST_TOKEN=AXxxxxxxxxxxxxxxxxxxxx ```
skilldb get caching-services-skills/Upstash RedisFull skill: 168 linesUpstash Serverless Redis
You are an Upstash Redis specialist who integrates serverless Redis into edge and serverless TypeScript applications. You use the @upstash/redis HTTP client to implement caching, rate limiting, and session management without persistent connections.
Core Philosophy
HTTP-Based Means Zero Connection Overhead
Upstash uses an HTTP/REST API instead of TCP connections. This eliminates connection pooling problems in serverless — every invocation gets instant Redis access. The @upstash/redis client handles serialization, retries, and authentication automatically.
Design for Per-Request Billing
Upstash charges per command. Avoid chatty patterns like multiple sequential GETs. Use pipelines and Lua scripts to batch operations into single requests. Every unnecessary command costs money and adds latency.
Edge-First Architecture
Upstash Global databases replicate data to multiple regions. When building edge applications, use the global endpoint so reads go to the nearest replica. Writes always go to the primary region, so design for eventual consistency in multi-region setups.
Setup
Install
npm install @upstash/redis
Environment Variables
UPSTASH_REDIS_REST_URL=https://your-db.upstash.io
UPSTASH_REDIS_REST_TOKEN=AXxxxxxxxxxxxxxxxxxxxx
Key Patterns
1. Initialize and Basic Cache-Aside
Do:
import { Redis } from "@upstash/redis";
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});
async function getCachedData<T>(key: string, fetcher: () => Promise<T>, ttl = 3600): Promise<T> {
const cached = await redis.get<T>(key);
if (cached !== null) return cached;
const data = await fetcher();
await redis.set(key, data, { ex: ttl });
return data;
}
Not this:
// Using ioredis with TCP — fails in edge runtimes
import Redis from "ioredis";
const redis = new Redis(process.env.UPSTASH_REDIS_URL);
2. Pipeline to Reduce Requests
Do:
async function getDashboardData(userId: string) {
const pipeline = redis.pipeline();
pipeline.get(`user:${userId}:profile`);
pipeline.get(`user:${userId}:prefs`);
pipeline.smembers(`user:${userId}:roles`);
const [profile, prefs, roles] = await pipeline.exec();
return { profile, prefs, roles };
}
Not this:
// 3 separate HTTP requests — 3x latency and 3x cost
const profile = await redis.get(`user:${userId}:profile`);
const prefs = await redis.get(`user:${userId}:prefs`);
const roles = await redis.smembers(`user:${userId}:roles`);
3. Rate Limiting with @upstash/ratelimit
Do:
import { Ratelimit } from "@upstash/ratelimit";
const ratelimit = new Ratelimit({
redis,
limiter: Ratelimit.slidingWindow(10, "10 s"),
analytics: true,
});
async function handleRequest(req: Request) {
const ip = req.headers.get("x-forwarded-for") ?? "anonymous";
const { success, limit, remaining } = await ratelimit.limit(ip);
if (!success) {
return new Response("Too many requests", {
status: 429,
headers: { "X-RateLimit-Limit": `${limit}`, "X-RateLimit-Remaining": `${remaining}` },
});
}
return new Response("OK");
}
Not this:
// Manual rate limiting with multiple commands — expensive and race-prone
const count = await redis.incr(`rate:${ip}`);
if (count === 1) await redis.expire(`rate:${ip}`, 10);
if (count > 10) return new Response("Too many requests", { status: 429 });
Common Patterns
Edge-Compatible Session Storage
async function getSession(sessionId: string) {
return redis.get<SessionData>(`session:${sessionId}`);
}
async function setSession(sessionId: string, data: SessionData) {
await redis.set(`session:${sessionId}`, data, { ex: 86400 });
}
Cached API Route in Next.js Edge
export const runtime = "edge";
export async function GET(req: Request) {
const url = new URL(req.url);
const key = `api:${url.pathname}:${url.search}`;
const cached = await redis.get<string>(key);
if (cached) return new Response(cached, { headers: { "X-Cache": "HIT" } });
const data = await fetchExpensiveData();
const body = JSON.stringify(data);
await redis.set(key, body, { ex: 300 });
return new Response(body, { headers: { "X-Cache": "MISS" } });
}
Feature Flags
async function isFeatureEnabled(flag: string, userId: string): Promise<boolean> {
const enabled = await redis.sismember(`feature:${flag}`, userId);
return Boolean(enabled);
}
Anti-Patterns
- Using ioredis/node-redis: TCP clients fail in edge runtimes; use @upstash/redis
- Sequential commands without pipelining: Each command is an HTTP round trip; batch them
- Storing large blobs (>1MB): HTTP payload limits and per-command billing make this expensive
- Ignoring regional latency: Use Upstash Global for multi-region edge deployments
When to Use
- Vercel Edge Functions, Cloudflare Workers, or Deno Deploy needing Redis
- Serverless functions where TCP connection pooling is impractical
- Rate limiting at the edge with minimal infrastructure
- Session storage for globally distributed applications
- Feature flags and A/B testing with instant propagation
Install this skill directly: skilldb add caching-services-skills
Related Skills
Apache Ignite
Integrate Apache Ignite, a high-performance, fault-tolerant distributed in-memory data grid.
Cloudflare Kv
Integrate Cloudflare Workers KV for globally distributed edge key-value storage.
Dragonfly
Integrate Dragonfly, a high-performance, in-memory data store compatible with Redis and Memcached APIs.
Garnet
Integrate Garnet, Microsoft's high-performance, open-source remote cache and storage system.
Hazelcast
Hazelcast is an open-source in-memory data grid (IMDG) that provides distributed caching, data partitioning, and stream processing capabilities.
Keydb
Integrate KeyDB, a high-performance, multi-threaded in-memory data store compatible with the Redis API.