Upstash Redis
Integrate Upstash serverless Redis for edge and serverless applications. Use the HTTP-based REST API for Vercel Edge Functions, Cloudflare Workers, and other environments without persistent TCP connections.
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: 167 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
Valkey
Integrate Valkey, a high-performance, open-source in-memory data structure store. Leverage its versatile data structures and Redis-compatible API for lightning-fast caching, real-time analytics, session management, and message brokering in demanding web applications.
Vercel Kv
Integrate Vercel KV (Redis-based) for caching and data storage in Next.js applications. Use the built-in SDK for edge-compatible key-value operations, rate limiting, and session management on Vercel's platform.
Apache Ignite
Integrate Apache Ignite, a high-performance, fault-tolerant distributed in-memory data grid. Leverage its capabilities for caching, database, and processing to achieve extreme scalability and low-latency data access in demanding web applications, making it ideal for real-time analytics, transactional systems, and compute-intensive tasks.
Cloudflare Kv
Integrate Cloudflare Workers KV for globally distributed edge key-value storage. Implement eventually consistent caching, static asset serving, and configuration management in Cloudflare Workers and Pages Functions.
Dragonfly
Integrate Dragonfly, a high-performance, in-memory data store compatible with Redis and Memcached APIs. Leverage its efficiency for caching, real-time data, and session management, reducing resource consumption and improving throughput for demanding web applications.
Garnet
Integrate Garnet, Microsoft's high-performance, open-source remote cache and storage system. Leverage its Redis-compatible API for extreme throughput and low-latency data access in demanding web applications, making it ideal for caching, session management, and real-time data needs.