ShipGuardScan a site

Rate Limiting AI Endpoints in Vibe-Coded Apps

Updated 2026-10-17

Even with the API key safely on the server, an unauthenticated or unlimited AI route lets anyone spend your budget through your app.

A simple fixed window

Count requests per user per minute and reject past the limit.

import { Redis } from "@upstash/redis";
const redis = Redis.fromEnv();
export async function allow(userId: string, limit = 20) {
  const key = `rl:${userId}:${Math.floor(Date.now() / 60000)}`;
  const n = await redis.incr(key);
  if (n === 1) await redis.expire(key, 70);
  return n <= limit;
}

Defence in depth

Require sign-in, cap input and output tokens, set provider spend limits, and alert on unusual usage.

Checklist

  • Auth required
  • Per-user limit
  • Per-IP limit for anonymous routes
  • Token caps
  • Provider spend limit

Copy-paste fix prompt

Add a per-user rate limit (20 requests/minute) and input length cap to every route that calls an LLM provider, require an authenticated session, and return HTTP 429 with a friendly message when exceeded.

FAQ

Is IP-based limiting enough?

It helps for anonymous routes but is easy to bypass. Prefer authenticated, per-user limits for expensive operations.

Where do I set spend limits?

In your AI provider's billing/usage settings; check what limits and alerts your plan supports.

Check your deployed app in ~25 seconds

Free passive scan: leaked keys, Supabase exposure, public config files and headers.

Run a free scan