Upstash Redis JS
UpstashOfficialCreated by Upstash
- Skill
- Tool integration
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a complete reference for the @upstash/redis SDK, an HTTP-based Redis client designed for serverless environments like Vercel, Cloudflare Workers, and edge runtimes. It covers core data structures, advanced features like pipelines and Lua scripting, common architectural patterns such as caching and session management, and migration paths from traditional Redis clients. The SDK features automatic serialization of JavaScript types, simplifying data handling for developers.
What it does
- Provides methods for interacting with Redis data structures including strings, hashes, lists, sets, sorted sets, and JSON.
- Supports advanced Redis features like pipelines, MULTI/EXEC transactions, and Lua scripting.
- Includes patterns for implementing caching, rate limiting, distributed locks, and session management.
- Enables vector search and full-text search capabilities within Redis.
- Handles automatic serialization and deserialization of native JavaScript types.
- Offers migration guidance for developers moving from ioredis or node-redis.
When to use it
- When building serverless applications that require a Redis-compatible key-value store.
- When implementing caching, session storage, or leaderboards in edge runtimes.
- When you need to perform atomic operations or complex server-side logic via Lua scripts.
- When migrating existing Node.js applications to a serverless architecture.
- When integrating AI agent memory or RAG tools using Redis.
Advantages
- Serverless-friendly HTTP-based architecture eliminates connection pooling issues.
- Automatic serialization removes the need for manual JSON parsing.
- Comprehensive support for modern Redis features including JSON and vector search.
- Well-defined patterns for common use cases like rate limiting and distributed locks.
- Seamless integration with popular frameworks like Next.js and Vercel.
Usage examples
- “How do I store a user object in Redis using the Upstash SDK?”
- The agent will demonstrate using redis.set('user:1', { name: 'Alice' }), highlighting that the SDK automatically handles JSON serialization.
- “Show me how to implement a simple counter in Redis.”
- The agent will provide code using redis.incr('counter') and explain that the SDK returns the incremented number directly without manual parsing.
- “How can I perform multiple operations atomically?”
- The agent will explain the use of redis.multi() or pipelines to batch commands and ensure atomic execution.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/upstash/upstash-redis-js/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip upstash-redis-js.zip -d .agents/skills
Documentation by Upstash
Upstash Redis SDK - Complete Skills Guide
This directory contains comprehensive guides for using the @upstash/redis SDK. These skill files are designed to help developers and AI assistants understand and use the SDK effectively.
Bundled docs and source
Before writing or debugging SDK code, check node_modules/@upstash/redis/docs/ for bundled docs and node_modules/@upstash/redis/src/ for readable TypeScript source. Read and search the relevant files when present; otherwise use the references in this skill.
Installation
npm install @upstash/redisQuick Start
Basic Initialization
import { Redis } from "@upstash/redis";
// Initialize with explicit credentials
const redis = new Redis({
url: "UPSTASH_REDIS_REST_URL",
token: "UPSTASH_REDIS_REST_TOKEN",
});
// Or initialize from environment variables
const redis = Redis.fromEnv();Environment Variables
Set these in your .env file:
UPSTASH_REDIS_REST_URL=https://your-redis.upstash.io
UPSTASH_REDIS_REST_TOKEN=your-token-hereNo credentials yet? If you're an agent that needs scratch Redis and the user hasn't provided a database, you can mint a temporary one with a single POST to
https://upstash.com/start-redis(3-day TTL, no signup).
Skill Files Overview
Data Structures (data-structures/)
Redis data types with auto-serialization examples:
strings.md - GET, SET, INCR, DECR, APPEND with automatic type handling
hashes.md - HSET, HGET, HMGET with object serialization
lists.md - LPUSH, RPUSH, LRANGE with array handling
sets.md - SADD, SMEMBERS, set operations
sorted-sets.md - ZADD, ZRANGE, ZRANK, leaderboard patterns
json.md - JSON.SET, JSON.GET, JSONPath queries for nested objects
streams.md - XADD, XREAD, XGROUP, consumer groups
arrays.md - ARSET, ARINSERT, ARSCAN, ARGREP, AROP, ring buffers with ARRING on sparse index-addressed arrays
vector-indexes.md - VECTOR.CREATE, VECTOR.ADD, VECTOR.QUERY nearest-neighbour search inside Redis via redis.vector
Advanced Features (advanced-features/)
Complex operations and optimizations:
auto-pipeline.md - Automatic request batching, performance optimization
pipeline-and-transactions.md - Manual pipelines, MULTI/EXEC for atomic operations
scripting.md - Lua scripts, EVAL, EVALSHA for server-side logic
Patterns (patterns/)
Common use cases and architectural patterns:
caching.md - Cache-aside, write-through, TTL strategies
rate-limiting.md - Integration with @upstash/ratelimit package
session-management.md - Session storage and user state management
distributed-locks.md - Lock implementations, deadlock prevention
leaderboard.md - Sorted set leaderboards, real-time rankings
Performance (performance/)
Optimization techniques and best practices:
batching-operations.md - MGET, MSET, batch operations
pipeline-optimization.md - When to use pipelines, performance tips
ttl-expiration.md - Key expiration strategies, memory management
data-serialization.md - Deep dive into auto serialization, custom serializers, edge cases
error-handling.md - Error types, retry strategies, timeout handling, debugging tips
redis-replicas.md - Global database setup, read replicas, read-your-writes consistency
Search (search/)
Full-text search, filtering, and aggregation extension for Redis:
overview.md - Schema definition, field types, pitfalls, package overview
commands/querying.md - Query and count with filters, pagination, sorting, highlighting
commands/aggregating.md - Metric aggregations ($avg, $sum, $stats), bucket aggregations ($terms, $range, $histogram, $facet)
commands/index-management.md - Create, describe, drop indexes (including stream indexes over XADD entries), waitIndexing
commands/aliases.md - Index aliases for zero-downtime reindexing
adapters.md - Using search with node-redis and ioredis via @upstash/search-redis and @upstash/search-ioredis
Migrations (migrations/)
Migration guides from other libraries:
from-ioredis.md - Migration from ioredis, key differences, serialization changes
from-redis-node.md - Migration from node-redis, API differences
Common Mistakes (Especially for LLMs)
❌ Mistake 1: Treating Everything as Strings
// ❌ WRONG - Don't do this with @upstash/redis
await redis.set("count", "42"); // Stored as string "42"
const count = await redis.get("count");
const incremented = parseInt(count) + 1; // Manual parsing needed
// ✅ CORRECT - Let the SDK handle it
await redis.set("count", 42); // Stored as number
const count = await redis.get("count");
const incremented = count + 1; // Just use it❌ Mistake 2: Manual JSON Serialization
// ❌ WRONG - Unnecessary with @upstash/redis
await redis.set("user", JSON.stringify({ name: "Alice" }));
const user = JSON.parse(await redis.get("user"));
// ✅ CORRECT - Automatic handling
await redis.set("user", { name: "Alice" });
const user = await redis.get("user");Quick Command Reference
// Strings
await redis.set("key", "value");
await redis.get("key");
await redis.incr("counter");
await redis.decr("counter");
// Hashes
await redis.hset("user:1", { name: "Alice", age: 30 });
await redis.hget("user:1", "name");
await redis.hgetall("user:1");
// Lists
await redis.lpush("tasks", "task1", "task2");
await redis.rpush("tasks", "task3");
await redis.lrange("tasks", 0, -1);
// Sets
await redis.sadd("tags", "javascript", "redis");
await redis.smembers("tags");
// Sorted Sets
await redis.zadd("leaderboard", { score: 100, member: "player1" });
await redis.zrange("leaderboard", 0, -1);
// JSON
await redis.json.set("user:1", "$", { name: "Alice", address: { city: "NYC" } });
await redis.json.get("user:1");
// Expiration
await redis.setex("session", 3600, { userId: "123" });
await redis.expire("key", 60);
await redis.ttl("key");Best Practices
Use environment variables for credentials, never hardcode
Leverage auto-serialization - pass native JavaScript types
Use TypeScript types for better type safety
Set appropriate TTLs to manage memory
Use pipelines for multiple operations
Namespace your keys (e.g.,
user:123,session:abc)
AI agents: use AgentKit
For agent state on Redis — memory, chat history, RAG search tools, tool caching, rate limiting, chat persistence, resumable streams, locks — use Upstash AgentKit instead of hand-rolling it on @upstash/redis. Pick the adapter for the framework and follow its docs page:
| Framework | Package | Docs |
|---|---|---|
| Vercel AI SDK | @upstash/agentkit-ai-sdk | https://upstash.com/docs/redis/sdks/agentkit/ai-sdk |
| TanStack AI | @upstash/agentkit-tanstack-ai | https://upstash.com/docs/redis/sdks/agentkit/tanstack-ai |
| Vercel Eve | @upstash/agentkit-eve, @upstash/agentkit-eve-extension | https://upstash.com/docs/redis/sdks/agentkit/eve |
Resources
Getting Help
For detailed information on specific topics, refer to the individual skill files in the skills/ directory. Each file contains comprehensive examples, use cases, and best practices for its topic.
Files
- ATTRIBUTION.mdAdded by AutoGineer883 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md9.1 KiB
- advanced-features/auto-pipeline.md1.3 KiB
- advanced-features/pipeline-and-transactions.md2.5 KiB
- advanced-features/scripting.md2.8 KiB
- data-structures/arrays.md3.7 KiB
- data-structures/hashes.md1.8 KiB
- data-structures/json.md3.6 KiB
- data-structures/lists.md2.1 KiB
- data-structures/sets.md2.8 KiB
- data-structures/sorted-sets.md3.9 KiB
- data-structures/streams.md5.0 KiB
- data-structures/strings.md2.1 KiB
- data-structures/vector-indexes.md2.5 KiB
- migrations/from-ioredis.md3.6 KiB
- migrations/from-redis-node.md4.2 KiB
- patterns/caching.md1.3 KiB
- patterns/distributed-locks.md3.6 KiB
- patterns/leaderboard.md4.1 KiB
- patterns/rate-limiting.md4.7 KiB
- patterns/session-management.md5.0 KiB
- performance/batching-operations.md2.0 KiB
- performance/data-serialization.md3.4 KiB
- performance/error-handling.md3.8 KiB
- performance/pipeline-optimization.md2.4 KiB
- performance/redis-replicas.md484 B
- performance/ttl-expiration.md775 B
- search/adapters.md2.8 KiB
- search/commands/aggregating.md5.8 KiB
- search/commands/aliases.md2.1 KiB
- search/commands/index-management.md4.6 KiB
- search/commands/querying.md6.6 KiB
- search/overview.md6.5 KiB
search/commands/index-management.md
Index Management
Overview
Create, inspect, and drop search indexes. Wait for indexing to complete after data changes. Indexes automatically track Redis keys matching a specified prefix, or the entries of a single stream.
Good For
Creating indexes over existing or new Redis data
Inspecting index schema and configuration
Rebuilding or dropping indexes
Ensuring data consistency after bulk writes
Examples
Create an Index
import { Redis, s } from "@upstash/redis";
const redis = Redis.fromEnv();
// JSON index with nested schema
const index = await redis.search.createIndex({
name: "products",
prefix: "product:",
dataType: "json",
schema: s.object({
name: s.string(),
price: s.number("F64"),
metadata: s.object({
brand: s.facet(),
tags: s.keyword(),
}),
}),
});
// Hash index (flat schema only)
const hashIndex = await redis.search.createIndex({
name: "sessions",
prefix: "session:",
dataType: "hash",
schema: {
userId: { type: "TEXT" as const },
lastActive: { type: "DATE" as const },
},
});Create a Stream Index
A stream index is bound to one exact stream key (no prefix). Every entry added with XADD becomes a document whose key is the entry ID. The stream does not need to exist yet, and entries removed with XDEL/XTRIM (or by deleting the stream) leave the index too.
const events = await redis.search.createIndex({
name: "event-search",
dataType: "stream",
stream: "events", // exact stream key, not a prefix
schema: s.object({
message: s.string(),
service: s.keyword(),
severity: s.number("U64"),
occurredAt: s.date().fast(),
}),
});
await redis.xadd("events", "*", {
message: "Payment authorization failed",
service: "checkout",
severity: 4,
occurredAt: new Date().toISOString(),
});
await events.waitIndexing();
const hits = await events.query({
filter: { message: "authorization", severity: { $gte: 3 } },
});
// [{ key: "1757000000000-0", score: 0.5, data: { message: "...", service: "checkout", severity: 4, ... } }]
// Read the full original entry by its ID
const entries = await redis.xrange("events", hits[0].key, hits[0].key);
const entry = entries[hits[0].key];Notes:
Stream schemas are flat (stream entries are flat field-value pairs).
Only one index can be bound to a stream at a time; drop it before binding another.
Search's document limit applies to stream entries: at the limit,
XADDto the indexed stream can fail.
Create with Options
const index = await redis.search.createIndex({
name: "articles",
prefix: ["article:", "post:"], // multiple prefixes
dataType: "json",
language: "english", // stemming language
skipInitialScan: false, // scan existing keys (default)
existsOk: true, // don't error if index already exists
schema: s.object({
title: s.string(),
body: s.string().noStem(),
publishedAt: s.date().fast(),
}),
});Get a Reference to an Existing Index
// If you already created the index and just need a reference
const index = redis.search.index({
name: "products",
schema: s.object({
name: s.string(),
price: s.number("F64"),
}),
});
// Without schema (untyped - no filter/select type safety)
const untypedIndex = redis.search.index({ name: "products" });Describe an Index
const description = await index.describe();
// {
// name: "products",
// dataType: "json", // "hash" | "string" | "json" | "stream"
// prefixes: ["product:"],
// language: "english",
// schema: { name: { type: "TEXT" }, price: { type: "F64", fast: true } }
// }
// Returns null if index doesn't exist
const missing = await redis.search.index({ name: "nonexistent" }).describe();
// nullWait for Indexing
// After inserting/updating/deleting data, wait for index to catch up
await redis.json.set("product:1", "$", { name: "Laptop", price: 999 });
await redis.json.set("product:2", "$", { name: "Mouse", price: 29 });
await redis.json.set("product:3", "$", { name: "Keyboard", price: 79 });
await index.waitIndexing(); // blocks until all pending docs are indexed
// Queries now reflect the latest data
const results = await index.query({ filter: { name: { $eq: "Laptop" } } });Drop an Index
const result = await index.drop();
// 1 if dropped, 0 if index didn't existSupported Languages
For stemming: english, french, spanish, portuguese, italian, german, dutch, swedish, norwegian, danish, finnish, hungarian, russian, romanian, turkish, arabic, chinese, japanese
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Node.js
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Upstash
- Publisher
- Upstash (Official)
- Source
- upstash/skills · skills/upstash-redis-js · commit 9f9e3e5
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Upstash or Upstash.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download upstash-redis-js.zip