Skip to main content
skill GitHub Copilot official · GitHub

upstash-redis — GitHub Copilot skill: what it does, how to install

Connect to Redis over HTTP in serverless runtimes using @upstash/redis and configure rate limiting with @upstash/ratelimit without TCP connection pooling.

Install into GitHub Copilot · Skills CLI (Vercel) All methods and platforms ↓
npx skills add github/awesome-copilot --skill upstash-redis
Open on GitHub

What upstash-redis does

This skill guides Copilot through implementing Redis operations over HTTP for Next.js route handlers, Cloudflare Workers, and Vercel. It provides step-by-step patterns for cache-aside with TTL, session storage with sliding expiration, and 429 rate limiters using sliding window or token bucket algorithms.

Every command runs as an HTTP request via global fetch. The SDK automatically serializes objects and arrays, so manual calls to JSON.stringify or parseInt will break data handling. Setup requires an Upstash Redis database along with UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN environment variables.

Install this if you deploy on edge runtimes or serverless platforms where TCP sockets are unavailable. Keep standard clients like ioredis on long-running servers, and avoid this skill for vector similarity search.

What it helps with

  • implement cache-aside caching with TTLs in serverless handlers
  • set up a 429 rate limiter using sliding window or token bucket
  • manage user sessions with sliding expiration times
  • query Redis over HTTP without managing TCP connection pools

Example prompts for the agent

  • Implement a sliding window rate limiter for this Next.js route handler using Upstash
  • Set up cache-aside with a 1-hour TTL for the getUser query using @upstash/redis
  • Create a session store in Upstash Redis with sliding 24-hour expiration

How to install upstash-redis

1Skills CLI (Vercel)

npx skills add github/awesome-copilot --skill upstash-redis

2GitHub CLI

gh skill install github/awesome-copilot upstash-redis

3Manually: put the files in place

.github/skills/upstash-redis/SKILL.md

From the same set554

The whole set →
git-commit official github This skill reviews Git changes, stages related files, and creates Conventional Commits. Use it when you want an agent to make one commit or split work into separate commits. GitHub Copilot 47,165installs excalidraw-diagram-generator official github Turn a plain-language description into an Excalidraw diagram. Useful for mapping processes, system structure, and relationships between entities. GitHub Copilot 31,639installs multi-stage-dockerfile official github This skill guides GitHub Copilot in writing multi-stage Dockerfiles for different languages and frameworks. Use it when the final runtime image should contain fewer build dependencies. GitHub Copilot 29,688installs documentation-writer official github Skill that turns the agent into a technical writer following the Diátaxis framework: tutorials, how-to guides, reference, and explanation. Proposes structure before writing. GitHub Copilot 27,757installs prd official github Turns a feature idea into a structured PRD with user stories, technical requirements, and risks. Use it when planning a software feature or an AI-powered one. GitHub Copilot 24,035installs refactor official github This skill reshapes existing code without changing its external behavior. Use it for gradual cleanup of large functions, duplication, weak types, and code smells. GitHub Copilot 22,321installs java-springboot official github Gives GitHub Copilot Spring Boot development practices, from project layout to tests and security. Use it when writing or reviewing Java application code. GitHub Copilot 21,272installs create-readme official github This skill reviews a project and creates a structured README.md. Use it when the repository needs clear documentation based on its actual files and code. GitHub Copilot 19,081installs

Similar

stripe-best-practices official Stripe Integration guide for Stripe in Codex: covers Checkout Sessions, Connect Accounts v2, tax setup, and restricted API keys. CX Codex GP ChatGPT 36installs stripe-best-practices official OpenAI This skill guides Stripe API choices for payments, subscriptions, marketplaces, and financial accounts. Use it when building or reviewing a Stripe integration. CX Codex GP ChatGPT 36installs chatgpt-app-submission official OpenAI Inspects a ChatGPT Apps MCP server and prepares the submission JSON. Use it before review to collect app info, test cases, and findings. CX Codex GP ChatGPT 29installs uml-and-software-architecture-visualization official OpenAI This skill helps choose a notation and format for UML diagrams, architecture maps, workflows, and data models. Use it when you need to describe how a system is structured or behaves. CX Codex GP ChatGPT 24installs cloud-solution-architect microsoft Equips your AI agent with Azure Architecture Center guidance. It helps select architecture styles and validate system designs against Well-Architected Framework pillars. Claude Code GitHub Copilot 117installs ai-sdk official Vercel Labs Provides Vercel AI SDK guidance for your coding agent. Helps build chat interfaces, streaming routes, tool calls, and agents without obsolete syntax. CX Codex GP ChatGPT 22installs mcp-builder official anthropics This skill walks through building an MCP server in TypeScript or Python, from reading the protocol spec to writing tests and evaluation questions. Claude Code Claude.ai 130,949installs google-agents-cli-adk-code official Google A reference skill for building ADK agents with tools, callbacks, state, and workflows. Use it when an agent project needs concrete API patterns or code examples. Claude Code CX Codex Cursor +1 511,400installs

Questions about upstash-redis

How to install upstash-redis in GitHub Copilot?

Run npx skills add github/awesome-copilot --skill upstash-redis in your project or add .github/skills/upstash-redis/SKILL.md.

What does the upstash-redis skill do?

It gives Copilot instructions to configure @upstash/redis and @upstash/ratelimit over HTTP in serverless and edge runtimes.

When should you avoid this skill?

Skip it on long-running servers with existing TCP connections like ioredis, or when you need vector similarity search.

Source text

SKILL.md · MIT
---
name: upstash-redis
description: >
  Use Redis over HTTP from serverless and edge runtimes with @upstash/redis, and
  add rate limiting with @upstash/ratelimit. Use when the user mentions Upstash
  Redis, needs Redis from a Next.js route handler or middleware, Vercel,
  Cloudflare Workers, Deno, or Bun without TCP connection pooling, or wants
  cache-aside with TTLs, a session store, counters, or a 429 rate limiter using
  fixed window, sliding window, or token bucket. DO NOT use for self-hosted or
  TCP Redis clients (ioredis, node-redis), Redis Cluster administration, or
  vector similarity search.
license: MIT
compatibility: "@upstash/redis 1.x, @upstash/ratelimit 2.x, Node.js 18+ or any runtime with global fetch"
metadata:
  author: Upstash
---

# Upstash Redis Skill

This skill covers the three things serverless apps most often need Redis for:
caching, sessions, and rate limiting. The client talks to Redis over HTTP, so
it works where a long-lived TCP connection does not (edge middleware, short
lived functions). Follow the steps in order; each ends with a checkpoint.

## Requirements and limitations

- An Upstash Redis database (hosted service; usage-based pricing with a free
  tier). Credentials are a REST URL and token from the database page.
- Environment variables `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN`.
- Every command is an HTTP request. Batch with `pipeline()` or `MGET`/`MSET`
  when you issue many commands per request; avoid `KEYS *` in production.
- Values are serialized automatically (objects, arrays, numbers round-trip).
  Do not `JSON.stringify` before `set` or `parseInt` after `get`.

## Step 1 — Install and create one client per module

```bash
npm install @upstash/redis @upstash/ratelimit
```

```ts
// lib/redis.ts
import { Redis } from "@upstash/redis";

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

Create the client at module scope, not inside the request handler, so
ephemeral caches and pipelines can be reused across invocations.

> **Checkpoint**: `await redis.ping()` returns `"PONG"`.

## Step 2 — Cache-aside with TTL

```ts
import { redis } from "@/lib/redis";

type User = { id: string; name: string; plan: "free" | "pro" };

export async function getUser(userId: string): Promise<User | null> {
  const key = `user:${userId}`;
  const cached = await redis.get<User>(key);
  if (cached) return cached;

  const user = await db.users.findById(userId); // your data source
  if (user) await redis.set(key, user, { ex: 3600 }); // 1 hour TTL
  return user;
}

export async function updateUser(userId: string, patch: Partial<User>) {
  const user = await db.users.update(userId, patch);
  await redis.set(`user:${userId}`, user, { ex: 3600 }); // write-through
  return user;
}

export async function deleteUser(userId: string) {
  await db.users.delete(userId);
  await redis.del(`user:${userId}`); // invalidate
}
```

Always set a TTL on cache entries; namespace keys (`user:123`, `session:abc`).

> **Checkpoint**: second call to `getUser` returns without hitting the database
> and `await redis.ttl("user:123")` is positive.

## Step 3 — Sessions with sliding expiration

```ts
import { redis } from "@/lib/redis";

const SESSION_TTL = 60 * 60 * 24; // 24 hours

export async function createSession(userId: string, data: Record<string, unknown>) {
  const sessionId = crypto.randomUUID();
  await redis.set(`session:${sessionId}`, { userId, ...data, createdAt: Date.now() }, { ex: SESSION_TTL });
  return sessionId;
}

export async function getSession<T = Record<string, unknown>>(sessionId: string) {
  const session = await redis.get<T>(`session:${sessionId}`);
  if (session) await redis.expire(`session:${sessionId}`, SESSION_TTL); // slide
  return session;
}

export async function destroySession(sessionId: string) {
  await redis.del(`session:${sessionId}`);
}
```

Store the session id in an `HttpOnly; Secure; SameSite` cookie; never put the
Redis token in client code.

> **Checkpoint**: `getSession` after `createSession` returns the object with
> `userId`; after `destroySession` it returns `null`.

## Step 4 — Rate limiting a route handler

```ts
// app/api/search/route.ts (Next.js App Router; same pattern for any fetch handler)
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 per 10 seconds
  prefix: "ratelimit:search", // isolate keys per limiter
});

export async function POST(request: Request) {
  const ip = request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? "anonymous";
  const { success, limit, remaining, reset } = await ratelimit.limit(ip);

  if (!success) {
    return new Response("Too Many Requests", {
      status: 429,
      headers: {
        "X-RateLimit-Limit": String(limit),
        "X-RateLimit-Remaining": String(remaining),
        "Retry-After": String(Math.max(0, Math.ceil((reset - Date.now()) / 1000))),
      },
    });
  }

  // handle the request
  return Response.json({ ok: true });
}
```

- Identifier: use the user id or API key when authenticated; fall back to IP.
- Algorithms: `Ratelimit.fixedWindow(n, "1 m")` (cheapest), `slidingWindow`
  (smooth boundaries, default choice), `tokenBucket(refill, "10 s", max)`
  (allows bursts). Windows accept `ms`, `s`, `m`, `h`, `d`.
- Tiers: create one `Ratelimit` per tier with different `prefix` values.
- Edge middleware / Cloudflare Workers with `analytics: true`: the result has a
  `pending` promise; pass it to `context.waitUntil(pending)` so background work
  finishes before the runtime exits.
- `reset` is a Unix timestamp in milliseconds.

> **Checkpoint**: the 11th request within 10 seconds returns 429 with a
> `Retry-After` header; after the window it succeeds again.

## Common pitfalls

- **Creating clients inside handlers**: the limiter's in-memory
  `ephemeralCache` only helps when the instance outlives the request.
- **Manual JSON**: `redis.set("k", JSON.stringify(v))` then `redis.get` returns
  an already-parsed object; double parsing throws.
- **No TTL on cache keys**: memory grows until eviction; always pass `{ ex }`.
- **Trusting `x-forwarded-for` blindly**: take the first hop, or use the
  platform's IP helper, when behind a proxy.
- **Forgetting `pending`** on edge runtimes with analytics or multi-region
  limiters.

## When NOT to use this skill

- Long-running servers with a TCP Redis connection already in place: keep
  ioredis/node-redis.
- Vector search or RAG: use a vector database skill instead.
- Sub-millisecond, in-process caching: use an in-memory LRU.

## References

- https://upstash.com/docs/redis/sdks/ts/overview
- https://upstash.com/docs/redis/sdks/ratelimit-ts/overview
- https://github.com/upstash/redis-js
- https://github.com/upstash/ratelimit-js

© Upstash · MIT · github/awesome-copilot

See also

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor