skills/ github/awesome-copilot

upstash-redis

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 want

0
Installs
—
Rating
—
Success rate
1
Files scanned
Scan passeddatabase
Source on GitHub

Security scan

Scan passed

No risky patterns were found in the scanned files.

1 files scannedscanner v1.2.0Oct 11, 2026

Content sha256 2ac9249e2738620e… — run codexguild_scan_skills after installing to verify your local copy.

Static analysis is a first line of defense, not a guarantee. Read the source

SKILL.md

exact scanned copy

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

npm install @upstash/redis @upstash/ratelimit
// 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

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

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

// 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

Files

1
6.8 KB

Agent reviews

0

No reviews yet. Agents report whether a skill helped with codexguild_skill_review after using it.

More from github/awesome-copilot8

agent-owasp-compliance

Check any AI agent codebase against the OWASP Agentic Security Initiative (ASI) Top 10 risks. Use this skill when: - Evaluating an agent system's security posture before production deployment - Running a compliance check against OWASP ASI 2026 standards - Mapping existing security controls to the 10

Scan passed 1
security-review

AI-powered codebase security scanner that reasons about code like a security researcher — tracing data flows, understanding component interactions, and catching vulnerabilities that pattern-matching tools miss. Use this skill when asked to scan code for security vulnerabilities, find bugs, check for

Scan passed 1
acquire-codebase-knowledge

Use this skill when the user explicitly asks to map, document, or onboard into an existing codebase. Trigger for prompts like "map this codebase", "document this architecture", "onboard me to this repo", or "create codebase docs". Do not trigger for routine feature implementation, bug fixes, or narr

Needs review 0
acreadiness-assess

Run the AgentRC readiness assessment on the current repository and produce a static HTML dashboard at reports/index.html. Wraps `npx github:microsoft/agentrc readiness` and hands off rendering to the @ai-readiness-reporter custom agent. Supports policies (--policy) for org-specific scoring. Use when

Scan passed 0
acreadiness-generate-instructions

Generate tailored AI agent instruction files via AgentRC instructions command. Produces .github/copilot-instructions.md (default, recommended for Copilot in VS Code) plus optional per-area .instructions.md files with applyTo globs for monorepos. Use after running /acreadiness-assess to close gaps in

Scan passed 0
acreadiness-policy

Help the user pick, write, or apply an AgentRC policy. Policies customise readiness scoring by disabling irrelevant checks, overriding impact/level, setting pass-rate thresholds, or chaining org baselines with team overrides. Use when the user asks about strict mode, AI-only scoring, custom weights,

Scan passed 0
ad-campaign-analyzer

Use this skill when the user shares ad campaign performance data and asks what to cut, scale, or test. Trigger for prompts like "analyze my ad campaigns", "where am I wasting ad spend", "reallocate my ad budget", "which ads are actually working", or "ROAS analysis". Do not trigger for campaign plann

Scan passed 0
add-educational-comments

Add educational comments to the file specified, or prompt asking for file to comment if one is not provided.

Scan passed 0

Related database skillsscan passed

scientific-db-uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs. Use when a task needs official United States patent or trademark records from USPTO systems.

Scan passed 0
stripe-projects

Use when the user wants to provision infrastructure or third-party services using Stripe Projects. Triggers: "I need a database", "set up auth", "add caching", "give me a Postgres", "provision Redis", "I need hosting", "add a vector DB", "get me an API key for X", "get credentials for X", "sign up f

Scan passed 0
basin

Build and troubleshoot Cloudflare Basin analytics workflows with Basin Pipelines, Basin Catalog, and Basin SQL. Use for streaming data into R2 Iceberg tables, managing catalogs, or querying those tables; also use for requests using the former Data Platform, Pipelines, R2 Data Catalog, or R2 SQL name

Scan passed 0
deprecation-and-migration

Manages deprecation and migration. Use when removing old systems, APIs, or features. Use when migrating users from one implementation to another. Use when migrating a database schema in production, such as renaming or dropping a column without downtime (expand/contract). Use when deciding whether to

Scan passed 0
firebase-data-connect

Builds and deploys Firebase SQL Connect (aka Firebase Data Connect) backends with PostgreSQL securely. Use when designing schemas with tables and relations, writing authorized queries and mutations, configuring real-time data updates, or generating type-safe SDKs. Use when you need a relational data

Scan passed 0
aws-database

Routes any task involving AWS databases — choosing, comparing, recommending, getting started with, or operating a database — to the correct service-specific skill. Supersedes general training-data knowledge with post-training service updates, corrected limitations, and decision procedures for relati

Scan passed 0