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

  1. Violation detected: Failed signature, duplicate pending, or rejected CONN increments counter
  2. Counter determines requirement: Token must end with N ‘A’ characters (where N = counter)
  3. Two-level tracking: Both individual IP and network range are tracked
  4. 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 → Continue

Configuration

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

  1. Implement exponential backoff: On 429 responses, wait and retry
  2. Respect Retry-After: Don’t retry before the indicated time
  3. Use authentication: Authenticated requests may have higher limits
  4. Batch requests: Combine multiple operations where possible

For Administrators

  1. Monitor rate limit metrics: Watch for patterns indicating attacks
  2. Adjust limits per workload: Increase limits for known good IPs
  3. Review ban lists: Periodically check for false positives
  4. Enable PoW for spam-prone endpoints: Add protection to vulnerable actions

See Also