Receber por email
← Voltar para o catálogo

api-database-upstash

Upstash serverless Redis -- REST-based client, auto-serialization, pipelines, rate limiting, QStash, edge compatibility, global replication

11estrelas
Atualizado há 7 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add agents-inc/skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/api-database-upstash/svg)](https://www.skillteca.com.br/skills/api-database-upstash)

Skills relacionadas

Ver todas de Dados e Análise →

Alerta por categoria

Receba novas skills de Dados e Análise toda segunda

1 email curto, só com as skills novas de Dados e Análise. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Upstash Patterns

Quick Guide: Upstash provides a REST/HTTP-based Redis client (@upstash/redis) designed for serverless and edge runtimes where TCP connections are unavailable. Unlike ioredis/node-redis, every command is an HTTP request -- no persistent connections, no connection pools, no teardown. The client automatically serializes/deserializes JSON (objects stored via set come back as objects from get), which is convenient but has gotchas with large numbers and cross-client compatibility. Use redis.pipeline() to batch commands into a single HTTP request, redis.multi() for atomic transactions, and @upstash/ratelimit for pre-built rate limiting algorithms. For background jobs, use @upstash/qstash which pushes messages to your API via HTTP webhooks.

<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST use Redis.fromEnv() for initialization in production code -- never hardcode UPSTASH_REDIS_REST_URL or UPSTASH_REDIS_REST_TOKEN values)

(You MUST handle the pending promise from @upstash/ratelimit responses in edge runtimes -- use context.waitUntil(pending) on Vercel Edge/Cloudflare Workers or analytics data is lost)

(You MUST use redis.pipeline() when issuing 3+ independent commands in a single handler -- each command is a separate HTTP round-trip without pipelining)

(You MUST NOT use Upstash for Pub/Sub, blocking commands (BRPOP, BLPOP, XREAD BLOCK), or Lua scripting -- REST API does not support these; use ioredis with a TCP connection instead)

</critical_requirements>

Examples

  • [Core Patterns](examples/core.md) -- Client setup, commands, auto-serialization, pipeline, transactions
  • [Rate Limiting](examples/rate-limiting.md) -- @upstash/ratelimit algorithms, middleware, analytics
  • [QStash](examples/qstash.md) -- Background jobs, scheduling, message publishing

Additional resources:

  • [reference.md](reference.md) -- Command cheat sheet, constructor options, environment variables, eviction policies

Auto-detection: Upstash, @upstash/redis, @upstash/ratelimit, @upstash/qstash, Redis.fromEnv, UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN, Ratelimit.slidingWindow, Ratelimit.fixedWindow, Ratelimit.tokenBucket, serverless Redis, edge Redis, REST Redis

When to use:

  • Serverless functions (AWS Lambda, Vercel, Netlify) that cannot maintain TCP connections
  • Edge runtimes (Cloudflare Workers, Vercel Edge, Fastly Compute) that only support HTTP
  • Rate limiting API routes with pre-built algorithms (sliding window, fixed window, token bucket)
  • Caching in serverless/edge where ioredis connection pooling is impractical
  • Background job scheduling with QStash (push-based, no long-running consumers needed)
  • Global read latency optimization via Upstash Global Database with read replicas

Key patterns covered:

  • @upstash/redis client setup with Redis.fromEnv() and constructor options
  • Automatic JSON serialization/deserialization behavior and gotchas
  • Pipeline batching (redis.pipeline()) and atomic transactions (redis.multi())
  • @upstash/ratelimit algorithms: sliding window, fixed window, token bucket
  • @upstash/qstash for serverless background jobs and scheduling
  • Global Database architecture (primary + read regions, eventual consistency)
  • Edge runtime compatibility and context.waitUntil() patterns

When NOT to use:

  • Long-running servers with persistent connections (use ioredis -- lower latency per command via TCP)
  • Pub/Sub, blocking commands, or Lua scripting (REST API does not support these)
  • Write-heavy workloads on Global Database (writes always go to primary region)
  • Latency-critical paths where per-command HTTP overhead (~5-15ms) is unacceptable (use ioredis with TCP for <1ms per command)
  • Large payloads (>1 MB) -- REST API has payload size limits

<philosophy>

Philosophy

Upstash exists because serverless and edge runtimes cannot maintain TCP connections. Traditional Redis clients (ioredis, node-redis) rely on persistent TCP sockets -- they fail in Cloudflare Workers, break in short-lived Lambda functions, and cannot run in browser/WebAssembly environments. Upstash replaces TCP with REST/HTTP, trading per-command latency (~5-15ms vs <1ms) for universal compatibility.

Core principles:

  1. Connectionless by design -- Every command is a stateless HTTP request. No connection pools, no teardown, no connection limits. This is a feature, not a limitation.
  2. Auto-serialization is default -- Objects go in, objects come out. No manual JSON.stringify/JSON.parse. This simplifies 90% of use cases but surprises developers who expect raw string behavior.
  3. Pipeline for performance -- Without pipelining, N commands = N HTTP requests. Always batch independent commands with redis.pipeline() to reduce round-trips.
  4. Rate limiting as a first-class citizen -- @upstash/ratelimit provides production-ready algorithms without writing Lua scripts. The library handles all the Redis plumbing internally.
  5. Push-based messaging -- QStash delivers messages TO your API via HTTP webhooks. No long-running consumer processes needed -- perfect for serverless.

</philosophy>

<patterns>

Core Patterns

Pattern 1: Client Setup with Redis.fromEnv()

Initialize using environment variables for zero-config deployment. See [examples/core.md](examples/core.md) for full examples including constructor options and timeout configuration.

// Good Example
import { Redis } from "@upstash/redis";

const redis = Redis.fromEnv();
// Reads UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN automatically

export { redis };

Why good: Zero-config, environment variables injected by platform (Vercel, Fly.io), no secrets in code

// Bad Example
import { Redis } from "@upstash/redis";

const redis = new Redis({
  url: "https://us1-merry-cat-12345.upstash.io",
  token: "AXXXAAIgcDE...",
});

Why bad: Hardcoded credentials leak in version control, non-portable across environments

Pattern 2: Automatic JSON Serialization

Upstash auto-serializes objects with JSON.stringify on write and JSON.parse on read. See [examples/core.md](examples/core.md) for type-safe patterns and disabling auto-serialization.

// Good Example -- objects round-trip automatically
interface UserProfile {
  name: string;
  email: string;
  loginCount: number;
}

const CACHE_TTL_SECONDS = 3600;

await redis.set<UserProfile>(
  "user:123",
  {
    name: "Alice",
    email: "alice@example.com",
    loginCount: 42,
  },
  { ex: CACHE_TTL_SECONDS },
);

// Returns typed object -- no JSON.parse needed
const user = await redis.get<UserProfile>("user:123");
// user is UserProfile | null

Why good: TypeScript generics provide type safety, no manual serialization, TTL set via options object

// Bad Example -- unnecessary manual serialization
await redis.set("user:123", JSON.stringify({ name: "Alice" }));
const raw = await redis.get("user:123");
const user = JSON.parse(raw as string); // Double-serialized: "{\"name\":\"Alice\"}"

Why bad: Auto-serialization already calls JSON.stringify -- doing it manually results in double-encoded strings that return as escaped JSON

Pattern 3: Pipeline Batching

Batch multiple commands into a single HTTP request. Without pipelining, each command is a separate round-trip (~5-15ms each). See [examples/core.md](examples/core.md) for typed pipeline results.

// Good Example -- single HTTP request for all commands
const USER_TTL_SECONDS = 3600;

const pipe = redis.pipeline();
pipe.set("user:123:name", "Alice", { ex: USER_TTL_SECONDS });
pipe.set("user:123:email", "alice@example.com", { ex: USER_TTL_SECONDS });
pipe.incr("stats:signups");

const results = 
Compartilhar X LinkedIn