Rate Limiting

Multi-layer rate limiting to protect against abuse, brute force attacks, and DDoS.

Rate Limiters

ShipCommerce implements 4 different rate limiters:

LimiterLimitPurpose
Global100 req/min per IPOverall request limiting
Auth10 req/min per IPLogin/signup protection
API60 req/min per userAPI endpoint protection
Burst20 req/sec per IPSudden spike detection

How It Works

Rate limiting uses a sliding window algorithm:

  1. Each request is logged with timestamp
  2. Window slides to check requests in time period
  3. If count exceeds limit, request is rejected (429)
  4. Response includes retry-after header
// Rate limiter configuration
const rateLimiters = {
  global: {
    window: 60 * 1000,    // 1 minute
    max: 100,             // requests
    keyBy: 'ip',
  },
  auth: {
    window: 60 * 1000,    // 1 minute
    max: 10,              // requests
    keyBy: 'ip',
    routes: ['/api/auth/*'],
  },
  api: {
    window: 60 * 1000,    // 1 minute
    max: 60,              // requests
    keyBy: 'user',
    routes: ['/api/*'],
  },
  burst: {
    window: 1000,         // 1 second
    max: 20,              // requests
    keyBy: 'ip',
  },
};

Response Headers

Rate limit information is included in response headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704067200

# When rate limited (429 Too Many Requests)
Retry-After: 45

Burst Detection

The burst limiter detects sudden spikes that might indicate automated attacks:

  • Triggers when more than 20 requests in 1 second
  • Blocks IP for 60 seconds
  • Logs incident for review
  • Protects against DDoS and scraping

Auth Protection

Special protection for authentication endpoints:

  • Login attempts: 10 per minute per IP
  • Password reset: 5 per hour per email
  • Account creation: 5 per hour per IP
  • Failed attempts: Progressive delays
// Progressive delay on failed login attempts
Attempt 1-3:  No delay
Attempt 4-5:  5 second delay
Attempt 6-7:  15 second delay
Attempt 8+:   30 second delay + CAPTCHA

Exempt Routes

Some routes have modified or no rate limiting:

  • Static assets: No rate limiting (served by CDN)
  • Health checks: No rate limiting
  • Webhooks: Higher limits, verified by signature

Storage

Rate limit counters are stored in:

  • Development: In-memory store
  • Production: Redis (via Upstash) or Vercel KV

Vercel Edge: Rate limiting works at the edge, blocking bad requests before they reach your application code.

Monitoring

Rate limit events are logged for monitoring:

  • IP address and user ID (if authenticated)
  • Route that was rate limited
  • Number of requests in window
  • Timestamp and duration