█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/Programming Languages/REST APIs/Rate Limiting
50 minIntermediate

Rate Limiting

After this lesson, you will be able to: Implement rate limiting (token bucket, sliding window, fixed window) and communicate limits to clients.

Rate limiting protects your server from abuse + accidental traffic spikes. Production APIs always have it; clients always need to handle it gracefully.

Prerequisites:Versioning

Why rate limit

Prevent abuse (scraping, brute force, DoS). Enforce paid tiers (free: 100/hr, pro: 10k/hr). Protect backend services from spikes that would otherwise cascade. Industry standard: every modern public API rate limits.

Algorithms (pick one)

Fixed window: 'max 60 per minute'. Resets at minute boundary. Simple; burst at boundary risk. Sliding window: counts requests in the last 60 seconds, continuously. Smoother; more memory. Token bucket: refill at N tokens/sec, bucket holds M; spend a token per request. Allows bursts. Leaky bucket: queue of fixed size; process at constant rate. Smooths out bursts.

Communicate limits to clients

Standard rate-limit response headers.

css
// On every response
X-RateLimit-Limit: 60 // your max
X-RateLimit-Remaining: 42 // how many you have left
X-RateLimit-Reset: 1716781200 // unix time when the window resets
// IETF standard (newer; RFC 9331)
RateLimit-Limit: 60
RateLimit-Remaining: 42
RateLimit-Reset: 60 // seconds until reset
// When client exceeds:
HTTP/1.1 429 Too Many Requests
Retry-After: 30 // wait 30 seconds
{ "error": "RateLimitExceeded", "message": "Slow down, try again in 30s." }

Implementation with Redis + sliding window

Production-ready pattern.

tsx
// Sorted set per identity + 60-sec window
const window = 60_000; // ms
const max = 60;
async function check(ip: string): Promise<{ ok: boolean; remaining: number; resetAt: number }> {
const now = Date.now();
const key = `ratelimit:${ip}`;
const pipeline = redis.multi();
pipeline.zremrangebyscore(key, 0, now - window);
pipeline.zadd(key, now, `${now}-${Math.random()}`);
pipeline.zcard(key);
pipeline.expire(key, 60);
const [, , count] = await pipeline.exec();
const remaining = Math.max(0, max - count);
return { ok: count <= max, remaining, resetAt: now + window };
}

💡 Where to enforce

Edge (Cloudflare, AWS WAF): cheapest; stops attacks before they hit your servers. API gateway (Kong, AWS API Gateway): per-API + per-key limits with auth integration. Application: most flexible; per-user + per-endpoint custom logic. Combine: edge for DoS protection + app for business logic.

Common mistakes

Per-IP only (multiple users behind NAT get throttled together). No Retry-After header (clients keep hammering). Forgetting to rate-limit auth endpoints (brute-force attacks). Limiting AFTER doing expensive work (defeats the point, limit FIRST).

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←Versioning and Backwards Compatibility
Back to REST APIs
Testing REST APIs→