Skip to content
Back to skills

Rate Limiting

ASecurity

Rate limiting and throttling. Token bucket, sliding window, fixed window algorithms. Express rate limit, Spring rate limiting, Redis-based distributed rate limiting, and API quota management. USE WHEN: user mentions "rate limit", "throttle", "API quota", "too many requests", "429", "express-rate-limit", "sliding window", "token bucket" DO NOT USE FOR: circuit breaker patterns - use `resilience-patterns`; DDoS protection - use infrastructure/WAF solutions

  • 31 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 8, 2026
ai-agentstypescriptgojavaexpressspringapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add claude-dev-suite/claude-dev-suite --skill rate-limiting --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Rate Limiting?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Rate Limiting
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/claude-dev-suite-rate-limiting/badge)](https://www.skillsdirectory.com/skills/claude-dev-suite-rate-limiting)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: rate-limiting
description: |
  Rate limiting and throttling. Token bucket, sliding window, fixed window
  algorithms. Express rate limit, Spring rate limiting, Redis-based distributed
  rate limiting, and API quota management.

  USE WHEN: user mentions "rate limit", "throttle", "API quota", "too many requests",
  "429", "express-rate-limit", "sliding window", "token bucket"

  DO NOT USE FOR: circuit breaker patterns - use `resilience-patterns`;
  DDoS protection - use infrastructure/WAF solutions
allowed-tools: Read, Grep, Glob, Write, Edit
---
# Rate Limiting

## Express (express-rate-limit)

```typescript
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)

```typescript
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)

```java
@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

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

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…