A lightweight API rate-limiting gateway built with Flask. Sits in front of any upstream service and enforces configurable per-IP, per-endpoint rate limits stored in PostgreSQL and cached in Redis.
Client → FlowGuard (port 5000) → Upstream API (port 5001)
↕
Redis (cache + counters)
↕
PostgreSQL (rules store)
Every incoming request is matched against a rules table. The most specific rule wins (exact IP + exact endpoint > wildcard). If the limit is exceeded, FlowGuard returns 429 Too Many Requests without forwarding to upstream.
| Algorithm | Behaviour |
|---|---|
fixed_window |
Counts requests in fixed time slots (e.g. 0–60s, 60–120s) |
sliding_window |
Rolling window — smoother, no burst at window boundary |
token_bucket |
Allows short bursts, refills tokens at a steady rate |
Prerequisites: Python 3.12+, PostgreSQL, Redis
git clone https://github.com/your-username/FlowGuard.git
cd FlowGuard
python -m venv venv && source venv/bin/activate
pip install -r requirements.txtCopy and fill in env vars:
cp .env.example .envSet up the database:
psql -U postgres -f schema.sqlStart the gateway:
python app.pyList all rules:
curl http://localhost:5000/rulesCreate a rule:
curl -X POST http://localhost:5000/rules \
-H "Content-Type: application/json" \
-d '{
"endpoint": "/orders",
"algorithm": "sliding_window",
"limit_value": 5,
"window_seconds": 30
}'Rules are cached in Redis for 5 minutes (RULE_CACHE_TTL). Leave client_ip null to apply a rule to all IPs.
Tested with Locust — 20 concurrent users, 5/s spawn rate.
| Endpoint | Requests | Blocked (429) | Block Rate | Median Latency |
|---|---|---|---|---|
| GET /orders | 112 | 102 | 91% | 11ms |
| GET /products | 28 | 28 | 100% | 14ms |
Config:
/orders→ 5 req/30s (sliding window) ·/products→ 10 req/60s (default fixed window)
429 responses return in ~11ms since they short-circuit at the Redis layer — no upstream call is made.
locust -f locustfile.py
# Open http://localhost:8089