rate-limiting

Express (express-rate-limit)

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "rate-limiting" with this command: npx skills add claude-dev-suite/claude-dev-suite/claude-dev-suite-claude-dev-suite-rate-limiting

Rate Limiting

Express (express-rate-limit)

import rateLimit from 'express-rate-limit'; import RedisStore from 'rate-limit-redis'; import { createClient } from 'redis';

const redis = createClient({ url: process.env.REDIS_URL });

// Global rate limit const globalLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes limit: 100, standardHeaders: 'draft-7', legacyHeaders: false, store: new RedisStore({ sendCommand: (...args) => redis.sendCommand(args) }), message: { error: 'Too many requests, try again later' }, });

app.use(globalLimiter);

// Stricter limit on auth endpoints const authLimiter = rateLimit({ windowMs: 15 * 60 * 1000, limit: 5, keyGenerator: (req) => req.body.email || req.ip, // By email, not just IP store: new RedisStore({ sendCommand: (...args) => redis.sendCommand(args) }), });

app.use('/api/auth/login', authLimiter);

Redis Sliding Window (custom)

async function isRateLimited(key: string, limit: number, windowSec: number): Promise<boolean> { const now = Date.now(); const windowStart = now - windowSec * 1000;

const multi = redis.multi(); multi.zRemRangeByScore(key, 0, windowStart); // Remove old entries multi.zAdd(key, { score: now, value: ${now} }); multi.zCard(key); // Count in window multi.expire(key, windowSec);

const results = await multi.exec(); const count = results![2] as number; return count > limit; }

// Usage if (await isRateLimited(rl:${userId}, 100, 60)) { return res.status(429).json({ error: 'Rate limit exceeded' }); }

Algorithm Comparison

Algorithm Precision Memory Best For

Fixed window Low (burst at edges) Very low Simple APIs

Sliding window log High Medium Accurate limiting

Sliding window counter Medium Low Balance of accuracy & memory

Token bucket Medium Low Burst-friendly APIs

Spring Boot (Bucket4j)

@Bean public FilterRegistrationBean<RateLimitFilter> rateLimitFilter() { var filter = new RateLimitFilter( Bandwidth.classic(100, Refill.intervally(100, Duration.ofMinutes(1))) ); var registration = new FilterRegistrationBean<>(filter); registration.addUrlPatterns("/api/*"); return registration; }

Response Headers

// Standard rate limit headers (RFC draft-7) res.set({ 'RateLimit-Limit': '100', 'RateLimit-Remaining': ${remaining}, 'RateLimit-Reset': ${resetTimestamp}, 'Retry-After': ${retryAfterSeconds}, // On 429 responses });

Anti-Patterns

Anti-Pattern Fix

In-memory rate limiting in multi-server Use Redis-backed store

Rate limit by IP only Also limit by user ID or API key

No rate limit headers in response Send RateLimit-* headers for client awareness

Same limit for all endpoints Tighter limits on auth, webhooks, expensive ops

No Retry-After on 429 Include Retry-After header

Production Checklist

  • Redis-backed rate limiting for distributed deployments

  • Per-endpoint rate limit configuration

  • Standard rate limit headers in responses

  • Retry-After header on 429 responses

  • Rate limit by user ID (not just IP)

  • Monitoring: rate limit hit frequency

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

Skrape

Ethical web data extraction with robots exclusion protocol adherence, throttled scraping requests, and privacy-compliant handling ("Scrape responsibly!").

Registry SourceRecently Updated
590Profile unavailable
Coding

cron-scheduling

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

token-optimization

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

webrtc

No summary provided by upstream source.

Repository SourceNeeds Review