Rate Limiting
Overview
Cloudillo implements a sophisticated rate limiting system to protect against abuse, DDoS attacks, and credential stuffing. The system uses the Generic Cell Rate Algorithm (GCRA) with hierarchical address grouping and dual-tier limits.
Algorithm: GCRA
The rate limiter uses GCRA (Generic Cell Rate Algorithm), also known as the “leaky bucket as a meter” algorithm. GCRA provides:
- Smooth rate limiting: Distributes requests evenly over time
- Burst tolerance: Allows short bursts within limits
- Memory efficiency: O(1) per key, no per-request storage
- Precision: Nanosecond-level timing accuracy
Hierarchical Address Levels
Requests are rate-limited at multiple network levels simultaneously. All levels must pass for a request to succeed.
IPv4 Levels
| Level | Mask | Description | Example |
|---|---|---|---|
| Individual | /32 | Single IP address | 192.168.1.100 |
| Network | /24 | Class C network (256 IPs) | 192.168.1.0/24 |
IPv6 Levels
| Level | Mask | Description | Example |
|---|---|---|---|
| Subnet | /64 | Single subnet | 2001:db8:1234:5678::/64 |
| Provider | /48 | ISP allocation | 2001:db8:1234::/48 |
Multi-Level Protection
A single abusive IP can’t overwhelm the system, but neither can a botnet spread across a /24 network. Both individual and network-level limits apply.
Dual-Tier Limits
Each address level has two tiers of limits:
| Tier | Period | Purpose |
|---|---|---|
| Short-term | Per-second | Burst protection |
| Long-term | Per-hour | Sustained abuse protection |
Both tiers must pass. This prevents:
- Burst attacks: Limited by short-term tier
- Slow-and-steady attacks: Limited by long-term tier
Endpoint Categories
Different endpoints have different rate limit profiles:
Auth Category
Strict limits for authentication endpoints to prevent credential stuffing.
| Endpoint | Description |
|---|---|
POST /api/auth/login |
User login |
POST /api/profile/register |
New user registration |
POST /api/auth/password |
Password reset |
Default limits (per individual IPv4):
- Short-term: 2 req/s, burst 5
- Long-term: 30 req/h, burst 30
Federation Category
Moderate limits for inter-instance communication.
| Endpoint | Description |
|---|---|
POST /api/inbox |
Receive federated actions |
POST /api/inbox/sync |
Sync federated actions |
Default limits (per individual IPv4):
- Short-term: 5 req/s, burst 15
- Long-term: 1000 req/h, burst 100
General Category
Relaxed limits for normal browsing and API usage.
| Endpoint | Description |
|---|---|
GET /api/profiles/* |
Profile viewing |
GET /api/actions/* |
Action listing |
GET /api/files/* |
File access |
Default limits (per individual IPv4):
- Short-term: 20 req/s, burst 50
- Long-term: 5000 req/h, burst 500
WebSocket Category
Moderate limits for WebSocket connections.
| Endpoint | Description |
|---|---|
/ws/bus |
Notification bus |
/ws/crdt/* |
Collaborative editing |
/ws/rtdb/* |
Real-time database |
Default limits (per individual IPv4):
- Short-term: 10 req/s, burst 20
- Long-term: 200 req/h, burst 100
Default Rate Limits Table
| Category | IPv4 Individual | IPv4 Network | IPv6 Subnet | IPv6 Provider |
|---|---|---|---|---|
| Auth | 2/s, 30/h | 10/s, 300/h | 20/s, 600/h | 50/s, 3000/h |
| Federation | 5/s, 1000/h | 50/s, 5000/h | 10/s, 5000/h | 200/s, 20000/h |
| General | 20/s, 5000/h | 100/s, 50000/h | 100/s, 50000/h | 500/s, 200000/h |
| WebSocket | 10/s, 200/h | 50/s, 1000/h | 50/s, 1000/h | 200/s, 5000/h |
Proof-of-Work Protection
CONN (connection request) actions require proof-of-work when suspicious behavior is detected from an IP address.
How It Works
- Violation detected: Failed signature, duplicate pending, or rejected CONN increments counter
- Counter determines requirement: Token must end with N ‘A’ characters (where N = counter)
- Two-level tracking: Both individual IP and network range are tracked
- Automatic decay: Counter decreases by 1 every hour without new violations
Violation Types
| Reason | Level | Description |
|---|---|---|
ConnSignatureFailure |
Individual + Network | CONN action failed signature verification |
ConnDuplicatePending |
Individual + Network | Duplicate CONN while another is pending |
ConnRejected |
Individual only | CONN rejected by user or policy |
ConnPowCheckFailed |
Network only | Failed PoW verification |
PoW Requirement
The PoW requirement is a simple suffix check on the action token:
Counter = 0: No requirement
Counter = 1: Token must end with "A"
Counter = 2: Token must end with "AA"
Counter = 3: Token must end with "AAA"
...
Counter = 10: Token must end with "AAAAAAAAAA"When PoW is required, the server responds with HTTP 428 (Precondition Required) and the required suffix.
Verification Flow
CONN action received at /api/inbox
↓
Check PoW requirement for source IP
↓
Requirement > 0?
├─ Yes → Check token.ends_with("A" × N)
│ ├─ Pass → Process action
│ └─ Fail → 428 Precondition Required
└─ No → Process action
↓
Violation during processing?
├─ Yes → Increment counter for IP/network
└─ No → ContinueConfiguration
| Parameter | Default | Description |
|---|---|---|
max_counter |
10 | Maximum requirement (10 ‘A’ characters) |
decay_interval_secs |
3600 | Counter decay interval (1 hour) |
max_individual_entries |
50,000 | LRU cache size for individual IPs |
max_network_entries |
10,000 | LRU cache size for network ranges |
Address Tracking
| Level | IPv4 | IPv6 | Purpose |
|---|---|---|---|
| Individual | /32 | /64 | Single source penalties |
| Network | /24 | /64 | Distributed attack protection |
The effective requirement is the maximum of individual and network counters.
HTTP Response Headers
Rate-limited responses include informative headers:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1735003600
X-RateLimit-Level: ipv4_individual| Header | Description |
|---|---|
Retry-After |
Seconds until request can be retried |
X-RateLimit-Limit |
Maximum requests per period |
X-RateLimit-Remaining |
Requests remaining in period |
X-RateLimit-Reset |
Unix timestamp when limit resets |
X-RateLimit-Level |
Which address level triggered the limit |
Configuration
Rate limits can be configured per-tenant via settings:
{
"rateLimit.auth.ipv4Individual.shortRps": 2,
"rateLimit.auth.ipv4Individual.shortBurst": 5,
"rateLimit.auth.ipv4Individual.longRph": 30,
"rateLimit.auth.ipv4Individual.longBurst": 30
}Monitoring
The rate limiter exposes statistics for monitoring:
| Metric | Description |
|---|---|
total_limited |
Total requests rate-limited |
total_bans |
Total IPs banned |
active_bans |
Current active ban count |
cache_size |
Current tracked IP count |
Best Practices
For API Clients
- Implement exponential backoff: On 429 responses, wait and retry
- Respect Retry-After: Don’t retry before the indicated time
- Use authentication: Authenticated requests may have higher limits
- Batch requests: Combine multiple operations where possible
For Administrators
- Monitor rate limit metrics: Watch for patterns indicating attacks
- Adjust limits per workload: Increase limits for known good IPs
- Review ban lists: Periodically check for false positives
- Enable PoW for spam-prone endpoints: Add protection to vulnerable actions
See Also
- System Overview - Architecture overview
- Actions API - Action rate limits
- Federation - Federation rate limits