Skip to content
Skillpedia
Automations48k · #4457

upstash-ratelimit

Adds request limits to APIs and functions. It uses Redis to control access and prevent overload, ensuring stability.

What it does

This tool helps control how many times a user or system can access a specific part of a website or app within a certain time. This prevents abuse by stopping someone from making too many requests too quickly.

When to use it

  • ✓Protecting contact forms from spam.
  • ✓Limiting login attempts to prevent attacks.
  • ✓Controlling API usage to avoid overload.

Example of what to ask your AI

“I want to limit access to my login page to a maximum of 5 attempts per minute per user.”

Want more? Open the sections below.

How to use

The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.

Skill link

https://github.com/sickn33/agentic-awesome-skills/blob/main/plugins/agentic-awesome-skills-claude/skills/upstash-ratelimit/SKILL.md

Ready-to-paste message

Use this skill to help me: https://github.com/sickn33/agentic-awesome-skills/blob/main/plugins/agentic-awesome-skills-claude/skills/upstash-ratelimit/SKILL.md Read the SKILL.md file at that link and follow its instructions for my task.
How it works

The tool uses a database called Redis to count requests. Each time someone accesses something protected, a counter is updated in Redis. If the counter reaches the limit, access is temporarily blocked.

Installation

Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.

In the terminal (Claude Code, Codex, Cursor), in your project folder:

npx skills add sickn33/agentic-awesome-skills --skill upstash-ratelimit

Or download just the file:

curl -L https://raw.githubusercontent.com/sickn33/agentic-awesome-skills/main/plugins/agentic-awesome-skills-claude/skills/upstash-ratelimit/SKILL.md -o SKILL.md
Technical content (original SKILL.md)

Original text by the author, straight from GitHub.

Upstash Ratelimit

Overview

@upstash/ratelimit implements distributed rate limiting on top of Upstash Redis. Because state lives in Redis, every instance of a serverless function or edge worker shares the same counters, which an in-memory limiter cannot do. It ships three algorithms (fixed window, sliding window, token bucket), per-identifier keys, optional in-memory blocking of already-limited identifiers, and optional analytics.

When to Use This Skill

  • Use when the user needs to limit requests per IP, user, API key, or tenant across multiple serverless instances or regions.
  • Use when protecting login, signup, form, webhook, or LLM endpoints from abuse and returning 429 Too Many Requests.
  • Use when choosing between fixed window, sliding window, and token bucket.
  • Do not use for client-side retry/backoff against a third-party API's limits; see api-rate-limit-handler.
  • Do not use for a single long-running process with no shared state; an in-memory limiter is simpler there.

How It Works

Step 1: Install and configure

npm install @upstash/ratelimit @upstash/redis

Set UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN in the environment.

Step 2: Create the limiter once, outside the handler

import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";

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

Constructing the limiter at module scope lets the built-in ephemeral cache short-circuit blocked identifiers without a Redis call.

Step 3: Call limit() with a stable identifier

const { success, limit, remaining, reset, pending } = await ratelimit.limit(userId);

success is false when the identifier is over its limit. reset is a Unix timestamp in milliseconds. pending is a promise for background work (analytics, multi-region sync); await it or pass it to waitUntil on edge runtimes so the function is not frozen before it completes.

Examples

Example 1: Next.js middleware returning 429

import { Ratelimit } from "@upstash/ratelimit";
import { Redis } from "@upstash/redis";
import { NextResponse, type NextRequest } from "next/server";

const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(20, "1 m"),
});

export async function middleware(request: NextRequest) {
  const ip = request.headers.get("x-forwarded-for") ?? "anonymous";
  const { success, limit, remaining, reset } = await ratelimit.limit(ip);

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

export const config = { matcher: "/api/:path*" };

Example 2: Token bucket with per-plan limits

const limiters = {
  free: new Ratelimit({
    redis: Redis.fromEnv(),
    prefix: "rl:free",
    limiter: Ratelimit.tokenBucket(5, "10 s", 10), // refill 5 per 10 s, burst 10
  }),
  pro: new Ratelimit({
    redis: Redis.fromEnv(),
    prefix: "rl:pro",
    limiter: Ratelimit.tokenBucket(50, "10 s", 100),
  }),
};

const { success } = await limiters[plan].limit(apiKey);

Best Practices

  • ✅ Use a stable, low-cardinality identifier (user id, API key, tenant) where possible; fall back to IP only for anonymous traffic.
  • ✅ Set a distinct prefix per endpoint or plan so limits do not collide.
  • ✅ Return Retry-After and X-RateLimit-* headers with 429 responses.
  • ✅ Prefer slidingWindow for most APIs; use tokenBucket when short bursts are acceptable; use fixedWindow when the lowest Redis cost matters.
  • ❌ Don't construct a new Ratelimit inside the request handler.
  • ❌ Don't rely on pending completing on its own in edge runtimes.
  • ❌ Don't rate limit by x-forwarded-for without validating it is set by your proxy; clients can spoof it otherwise.

Limitations

  • Requires an Upstash Redis database; it does not work with other Redis servers or without network access.
  • Each limit() call is at least one HTTP round trip to Redis, so it adds latency to every request it guards.

…

FAQ

What happens if the limit is reached?

The person who exceeded the limit will receive an error message (429 code) and won't be able to access the resource for a while.

Can I set different limits for different users?

Yes, you can set limits based on unique identifiers like user ID, API key, or even IP address.

Do I need a special server to use this?

Yes, this tool requires an Upstash Redis database, which is a separate service.

Details

Original description by the author

Add rate limiting to API routes, middleware, and edge functions with @upstash/ratelimit: sliding window, fixed window, and token bucket backed by Upstash Redis.

repo: sickn33/agentic-awesome-skills

Popularity

GitHub stars
48k
Ranking position
#4457
License
MIT
Updated
10/15/2026

Is this skill useful?

0

Sign in to vote.

Comments

  • …

More skills from this repository

Similar skills