upstash-redis

Use to add serverless Redis (caching, counters, sessions) or rate limiting over HTTP from edge/serverless runtimes.

Tech stack

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: upstash-redis
description: Use to add serverless Redis (caching, counters, sessions) or rate limiting over HTTP from edge/serverless runtimes.
license: MIT
---

# Upstash Redis — Skillship

> Serverless, HTTP-based Redis that works from edge/serverless runtimes (Vercel, Cloudflare Workers,
> Lambda) where raw TCP is restricted. Pay-per-request, scales to zero.

## 🧭 When to use this skill
- Use when: you need caching, counters, sessions, queues, or rate limiting in serverless/edge code.
- Use when: your runtime can't open TCP sockets (edge) — Upstash speaks HTTP/REST.
- Don't use for: relational data or transactions across tables (use Postgres).

## ⚡ Quickstart

### 1. Install
```bash
npm install @upstash/redis
# For rate limiting:
npm install @upstash/ratelimit
```

### 2. Configure env (Console → your DB → REST API)
```bash
UPSTASH_REDIS_REST_URL=https://<id>.upstash.io
UPSTASH_REDIS_REST_TOKEN=<token>
```

### 3. Minimal working example
```ts
import { Redis } from "@upstash/redis";

const redis = Redis.fromEnv(); // reads UPSTASH_REDIS_REST_URL/_TOKEN

await redis.set("counter", 0);
await redis.incr("counter");
const value = await redis.get<number>("counter");
```

## 🧩 Common recipes

### Recipe: Cache with TTL
```ts
await redis.set("user:42", JSON.stringify(user), { ex: 60 }); // expires in 60s
const cached = await redis.get<string>("user:42");
```

### Recipe: Data structures
```ts
await redis.zadd("scores", { score: 1, member: "team1" });   // sorted set
await redis.lpush("queue", "job-1");                          // list
await redis.hset("people", { name: "joe" });                 // hash
await redis.sadd("animals", "cat");                          // set
```

### Recipe: Rate limiting (sliding window)
```ts
import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";

const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(10, "10 s"), // 10 requests / 10s
  analytics: true,
});

const identifier = userId ?? ip;               // per-user or per-IP
const { success } = await ratelimit.limit(identifier);
if (!success) return new Response("Too many requests", { status: 429 });
```

### Recipe: Edge runtimes (Cloudflare Workers / Vercel Edge)
```ts
import { Redis } from "@upstash/redis/cloudflare"; // edge-safe import
// Ensure background analytics/replication finish before the runtime exits:
const { success, pending } = await ratelimit.limit("id");
context.waitUntil(pending); // Workers; on Vercel use waitUntil from the Functions API
```

## 🚀 Ship to production
- [ ] `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` set in the host env (Vercel/Workers secrets).
- [ ] Rate-limit background work awaited via `waitUntil(pending)` in edge/serverless.
- [ ] Choose a primary region near your writes; add read regions for global reads.
- [ ] Set TTLs on cache keys so memory/cost don't grow unbounded.
- [ ] Namespace keys (e.g. `prefix`) if sharing a DB across apps to avoid collisions.

## 🔐 Security & secrets
- The REST token grants full DB access — store as a secret, never ship to the browser bundle.
- For client-side reads, create a **read-only** token; never expose the read/write token publicly.

## 🐛 Common errors & fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| `fromEnv()` throws about missing env | Env vars not set / wrong names | Set `UPSTASH_REDIS_REST_URL` and `_TOKEN` exactly |
| Rate-limit counts/analytics missing on edge | Runtime exited before background ops | `context.waitUntil(pending)` |
| Values come back as strings, not objects | Redis stores strings | `JSON.stringify` on write, parse on read (or use typed `get<T>`) |
| Higher-than-expected cost | No TTLs / chatty polling | Add TTLs, cache aggressively, batch commands |

## 💰 Pricing gotchas
- Billed per request (command). MultiRegion replication and analytics add background commands per `limit()` call.

## 📚 Sources
- https://upstash.com/docs/redis/overall/getstarted
- https://upstash.com/docs/redis/sdks/ts/getstarted
- https://upstash.com/docs/redis/sdks/ratelimit-ts/gettingstarted

More API Design skills

← All API Design skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY