A production-grade API rate limiter built from scratch with Node.js, TypeScript, and Redis. Implements multiple algorithms with API key authentication, tiered limits, and a live React dashboard.
Every production API needs rate limiting. Instead of using an existing library, I built one from scratch to understand the internals — algorithm trade-offs, Redis data structures, distributed state, and HTTP standards.
- Two algorithms — sliding window and token bucket, switchable via environment variable
- Sliding window — eliminates fixed window boundary burst vulnerability using Redis sorted sets
- Token bucket — allows controlled bursting with continuous token refill
- API key authentication with tiered limits (free: 10 req/min, pro: 50 req/min, internal: unlimited)
- Standard HTTP headers — X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After
- Graceful degradation — fails open if Redis is unavailable
- Live dashboard — real-time request stats per user with progress bars and blocked state
- JWT-protected Admin API — manage users and tiers without redeploying
- Full test suite — Jest + Supertest
Client → Express Middleware → Redis (Upstash) → Route Handler
↑
Dashboard (React)
Admin → JWT Auth → Admin Routes → Redis
Node.js · TypeScript · Express · Redis (Upstash) · React · Vite · Tailwind · Jest · JWT
Fixed window stores one counter per user that resets every minute. Simple but vulnerable — a user can send double the allowed requests across a minute boundary.
Sliding window stores exact request timestamps in a Redis sorted set. Counts only requests within the last 60 seconds from right now, eliminating the boundary vulnerability.
Token bucket gives each user a bucket of tokens that refills at a constant rate. Allows short bursts while enforcing long-term limits. Used by GitHub, Stripe, and most CDNs.
cd server
npm install
cp .env.example .env
npm run seed
npm run devcd dashboard
npm install
npm run devcd server
npm testUPSTASH_REDIS_REST_URL=your_url_here
UPSTASH_REDIS_REST_TOKEN=your_token_here
RATE_LIMIT_STRATEGY=sliding_window # or token_bucket
JWT_SECRET=your_secret_here # for admin routesGET /ping
X-API-Key: your-api-keyX-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1712120060
Retry-After: 60 (only on 429)
POST /admin/users Add a new user
GET /admin/users List all users
PATCH /admin/users/:name Update user tier
DELETE /admin/users/:name Remove a user
| Name | Key | Tier | Limit |
|---|---|---|---|
| Alice | alice-key-123 | Pro | 50 req/min |
| Bob | bob-key-456 | Free | 10 req/min |
| Charlie | charlie-key-789 | Internal | Unlimited |
Made with ❤️ by shivxmsharma