skills/api-rate-limiting-throttling-expert/SKILL.md
Token bucket, sliding window, and Redis-based rate limiting for API protection. Activate on: rate limiting, throttling, token bucket, sliding window, API abuse, DDoS protection, quota management. NOT for: API gateway setup (use api-gateway-reverse-proxy-expert), caching (use cache-strategy-invalidation-expert).
npx skillsauth add curiositech/windags-skills api-rate-limiting-throttling-expertInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Implement fair, efficient rate limiting using token bucket, sliding window, and fixed window algorithms with Redis-backed distributed counters.
Activate on: "rate limiting", "throttling", "token bucket", "sliding window", "API abuse", "DDoS protection", "quota management", "429 Too Many Requests", "request limits"
NOT for: API gateway configuration → api-gateway-reverse-proxy-expert | Caching strategies → cache-strategy-invalidation-expert | WAF/firewall rules → relevant security skill
MULTI/EXEC or Lua scripts for distributed rate limitingX-RateLimit-Limit, X-RateLimit-Remaining, Retry-After| Domain | Technologies | |--------|-------------| | Algorithms | Token bucket, sliding window log, sliding window counter, fixed window | | Storage | Redis 7.4+, Valkey, DragonflyDB, in-memory (single node) | | Libraries | rate-limiter-flexible, @upstash/ratelimit, express-rate-limit | | Gateway Plugins | Kong rate-limiting, Nginx limit_req, Traefik ratelimit | | Standards | RFC 6585 (429), RateLimit headers (draft-ietf-httpapi-ratelimit) |
-- Redis Lua script: sliding window rate limiter
-- KEYS[1] = rate limit key
-- ARGV[1] = window size (seconds)
-- ARGV[2] = max requests
-- ARGV[3] = current timestamp
local key = KEYS[1]
local window = tonumber(ARGV[1])
local limit = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
-- Remove expired entries
redis.call('ZREMRANGEBYSCORE', key, 0, now - window)
-- Count current window
local count = redis.call('ZCARD', key)
if count < limit then
redis.call('ZADD', key, now, now .. '-' .. math.random(1000000))
redis.call('EXPIRE', key, window)
return {1, limit - count - 1} -- allowed, remaining
else
return {0, 0} -- denied, 0 remaining
end
Request → IP Rate Limit (100/min)
│ pass
↓
Auth Check → API Key Rate Limit (tier-based)
│ Free: 60/min
│ Pro: 600/min
│ Enterprise: 6000/min
↓ pass
Endpoint Rate Limit (per-route)
│ POST /upload: 10/min
│ GET /search: 120/min
↓ pass
Process Request
// Middleware: attach rate limit headers
function rateLimitHeaders(limit: number, remaining: number, resetAt: number) {
return {
'RateLimit-Limit': limit.toString(),
'RateLimit-Remaining': Math.max(0, remaining).toString(),
'RateLimit-Reset': Math.ceil((resetAt - Date.now()) / 1000).toString(),
};
}
// On 429 response:
res.status(429).set({
...rateLimitHeaders(limit, 0, resetAt),
'Retry-After': Math.ceil((resetAt - Date.now()) / 1000).toString(),
}).json({ error: 'Too Many Requests', retryAfter: resetAt });
Retry-After force clients to guess, leading to thundering herdRateLimit-Limit, RateLimit-Remaining, RateLimit-Reset headers on every responseRetry-After header on 429 responsesdata-ai
license: Apache-2.0 NOT for unrelated tasks outside this domain.
development
Use when designing caching strategies (cache-aside, write-through, write-behind), implementing distributed locks, building rate limiters, leaderboards, real-time streams (XADD/consumer groups), pub/sub, or tuning eviction policies. Triggers: thundering-herd on cache miss, dogpile on key expiry, Redlock vs SET-NX-PX choice, sliding-window rate limiter, hot-key on a single cluster slot, big-key blowup, MULTI/EXEC across slots, KEYS in production. NOT for Redis Cluster operations/admin (different domain), embedded KV (SQLite, leveldb), in-process LRU caches, or Memcached.
tools
Drawing the `'use client'` boundary correctly in React Server Components apps (Next.js App Router, RSC frameworks) — leaf-pushing, slot composition, serialization rules, and environment poisoning prevention. Grounded in react.dev and Next.js 16 docs.
development
Use when designing rate limiting for an API, choosing between token bucket / sliding window / leaky bucket / fixed window, implementing it in Redis, deciding edge (Cloudflare/Upstash) vs origin enforcement, sizing per-user vs per-IP vs per-endpoint quotas, returning the right 429 response with Retry-After, or fixing the boundary-burst bug in fixed-window limiters. Triggers: 429 too many requests, INCR + EXPIRE, ZADD + ZREMRANGEBYSCORE + ZCARD, X-RateLimit-Remaining header, Cloudflare WAF rate limiting rules, Upstash @upstash/ratelimit, leaky bucket shaping vs policing, distributed rate limiter consistency. NOT for DDoS mitigation specifically (different scale), CAPTCHA / bot management, full WAF design, or per-user quota billing.