Systems & CLI · Intermediate
Distributed Rate Limiter & API Gateway
Build an API gateway that enforces per-key sliding-window rate limits across multiple nodes backed by Redis.
You will build a lightweight API gateway in Go that sits in front of upstream services and enforces per-API-key rate limits using a Redis-backed sliding-window algorithm. The gateway supports multiple concurrent instances sharing a single Redis cluster, so limits are consistent even when traffic is spread across nodes. This project teaches you how production systems like Cloudflare, Stripe, and GitHub enforce quotas at scale without per-request database writes.
What you build
- Per-API-key sliding-window rate limiting using Redis sorted sets with Lua atomicity
- Token-bucket fallback mode selectable per route via config
- HTTP reverse proxy that forwards allowed requests to a configurable upstream
- Standard 429 Too Many Requests responses with Retry-After and X-RateLimit-* headers
- Horizontally scalable: multiple gateway instances share state through a single Redis instance or cluster
- k6 load test suite that verifies limit enforcement under concurrent traffic
What it teaches
- Sliding-window and token-bucket rate-limiting algorithms and their trade-offs
- Writing atomic multi-step Redis operations with Lua scripts to avoid race conditions
- Building HTTP middleware chains and reverse proxies in Go's standard library
- Horizontal scaling patterns where distributed state lives in a shared cache rather than local memory
- Load testing concurrent systems with k6 and interpreting p99 latency under rate-limit pressure
How it works
- 1
Client
- Sends request with API key header
- 2
Gateway Node (any replica)
- Extract API key
- Run Lua script against Redis
- 3
Redis
- Atomic ZADD + ZCARD in sliding window
- Return count vs. limit
- 4
Decision
- Allow: forward to upstream
- Deny: return 429 + Retry-After
- 5
Upstream Service
- Receives only allowed traffic
- Returns response to client
Sign in to open the build guide
Free account. Get the step-by-step build and every resource link.
Take it further
- Add a circuit-breaker that opens when the upstream returns too many 5xx responses, short-circuiting requests without hitting Redis.
- Expose a Prometheus `/metrics` endpoint and wire a Grafana dashboard showing requests/sec, reject rate, and Redis latency per key.
- Support tiered limits stored in Redis hashes (free: 100/min, pro: 1000/min) and resolve the tier from a JWT claim on each request.


