High-performance rate limiting for any application. Choose between an embedded Rust library or a standalone server supporting HTTP, gRPC, and Redis protocols.
# Install and run the server
cargo install throttlecrab-server
throttlecrab-server --http --http-port 8080
# Test it with curl
curl -X POST http://localhost:8080/throttle \
-H "Content-Type: application/json" \
-d '{"key": "test", "max_burst": 3, "count_per_period": 10, "period": 60}'
[dependencies]
throttlecrab = "0.4"
use throttlecrab::{RateLimiter, AdaptiveStore};
use std::time::SystemTime;
let mut limiter = RateLimiter::new(AdaptiveStore::new());
let (allowed, result) = limiter
.rate_limit("user:123", 10, 100, 60, 1, SystemTime::now())
.unwrap();
if allowed {
println!("✅ Request allowed! {} remaining", result.remaining);
} else {
println!("❌ Rate limited! Retry in {}s", result.retry_after);
}
docker run -d -p 8080:8080 lazureykis/throttlecrab:latest
ThrottleCrab implements the Generic Cell Rate Algorithm (GCRA) for smooth, precise rate limiting without sudden bursts or unfair rejections. It's available as:
throttlecrab
- Embedded Rust library for in-process rate limitingthrottlecrab-server
- Standalone server supporting HTTP, gRPC, and Redis protocols
import requests
# Check rate limit
response = requests.post('http://localhost:8080/throttle', json={
'key': 'user:123',
'max_burst': 10,
'count_per_period': 100,
'period': 60
})
result = response.json()
if result['allowed']:
print(f"✅ Request allowed! {result['remaining']} remaining")
else:
print(f"❌ Rate limited! Retry in {result['retry_after']}s")
import redis
r = redis.Redis(host='localhost', port=6379)
result = r.execute_command('THROTTLE', 'user:123', 10, 100, 60)
# Returns: [allowed (0/1), limit, remaining, reset_after, retry_after]
const response = await fetch('http://localhost:8080/throttle', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
key: 'user:123',
max_burst: 10,
count_per_period: 100,
period: 60
})
});
const result = await response.json();
console.log(result.allowed ? '✅ Allowed' : '❌ Rate limited');
Protocol | Throughput | P99 Latency | P50 Latency |
---|---|---|---|
Redis | 184K req/s | 275 μs | 170 μs |
HTTP | 175K req/s | 327 μs | 176 μs |
gRPC | 163K req/s | 377 μs | 188 μs |
You can run the same benchmark yourself with cd integration-tests && ./run-transport-test.sh -t all -T 32 -r 10000
cargo install throttlecrab-server
throttlecrab-server --http --http-port 8080
docker run -d -p 8080:8080 -p 6379:6379 \
-e THROTTLECRAB_HTTP=true \
-e THROTTLECRAB_REDIS=true \
lazureykis/throttlecrab:latest
version: '3.8'
services:
throttlecrab:
image: lazureykis/throttlecrab:latest
ports:
- "8080:8080" # HTTP
- "6379:6379" # Redis
- "50051:50051" # gRPC
environment:
THROTTLECRAB_LOG_LEVEL: info
restart: unless-stopped
[Unit]
Description=ThrottleCrab Rate Limiting Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/throttlecrab-server --http --redis
Restart=always
[Install]
WantedBy=multi-user.target
All options can be set via CLI flags or environment variables:
# CLI flags
throttlecrab-server --http --http-port 8080 --store adaptive
# Environment variables
export THROTTLECRAB_HTTP=true
export THROTTLECRAB_HTTP_PORT=8080
export THROTTLECRAB_STORE=adaptive
throttlecrab-server
Store | Best For | Cleanup Strategy |
---|---|---|
adaptive |
Variable load (default) | Self-tuning |
periodic |
Predictable load | Fixed intervals |
probabilistic |
High throughput | Random sampling |
- Health:
GET /health
- Metrics:
GET /metrics
(Prometheus format)
Key metrics:
throttlecrab_requests_total
- Total requeststhrottlecrab_requests_allowed
- Allowed requeststhrottlecrab_requests_denied
- Denied requeststhrottlecrab_top_denied_keys
- Top denied keys
POST /throttle
{
"key": "string", # Unique identifier
"max_burst": 10, # Maximum burst capacity
"count_per_period": 100, # Allowed requests per period
"period": 60, # Period in seconds
"quantity": 1 # Optional, default 1
}
THROTTLE key max_burst count_per_period period [quantity]
PING
QUIT
See throttlecrab-server/proto/throttlecrab.proto
For best performance, use short keys:
- ✅ Good:
u:123
,ip:1.2.3.4
- ❌ Avoid:
user_id:123
,ip_address:1.2.3.4
Each entry stores:
- Key string: varies by length
- Value: i64 (8 bytes) + Option (24 bytes) = 32 bytes
- HashMap overhead: ~32 bytes per entry
Total per entry: ~64 bytes + key length
With 1M keys:
- 10-char keys: ~74 MB
- 50-char keys: ~114 MB
- 100-char keys: ~164 MB
- Vertical: Single instance handles 180K+ req/s
- Horizontal: Use client-side sharding by key
Contributions welcome! Please feel free to submit a Pull Request.