Sockudo
Server

Rate Limiting

Protect your server with sliding window rate limits for API and WebSocket connections.

Sockudo includes a built-in rate limiter that protects both the HTTP API and WebSocket connection endpoints. Rate limits use a sliding window algorithm and support multiple backends.

How It Works

The rate limiter tracks requests per client IP using a sliding time window. When a client exceeds the limit, further requests receive a 429 Too Many Requests response until the window resets.

Two independent rate limits are enforced:

LimitProtectsDefault
API rate limitHTTP API endpoints (/apps/{appId}/events, etc.)100 requests / 60 seconds
WebSocket rate limitNew WebSocket connections (/app/{appKey})20 connections / 60 seconds

Configuration

{
  "rate_limiter": {
    "enabled": true,
    "driver": "memory",
    "api_rate_limit": {
      "max_requests": 100,
      "window_seconds": 60,
      "trust_hops": 0
    },
    "websocket_rate_limit": {
      "max_requests": 20,
      "window_seconds": 60,
      "trust_hops": 0
    }
  }
}

API Rate Limit

SettingEnv VarDefaultDescription
max_requestsRATE_LIMITER_API_MAX_REQUESTS100Max requests per window
window_secondsRATE_LIMITER_API_WINDOW_SECONDS60Window duration in seconds
trust_hopsRATE_LIMITER_API_TRUST_HOPS0Trusted proxy hops (for X-Forwarded-For)

WebSocket Rate Limit

SettingEnv VarDefaultDescription
max_requestsRATE_LIMITER_WS_MAX_REQUESTS20Max connections per window
window_secondsRATE_LIMITER_WS_WINDOW_SECONDS60Window duration in seconds

Enable / Disable

RATE_LIMITER_ENABLED=true

Drivers

The rate limiter backend is configured separately from the cache driver:

DriverShared Across NodesExternal Dependency
memoryNoNone
redisYesRedis 6+
redis-clusterYesRedis Cluster 6+
noneN/ANone
RATE_LIMITER_DRIVER=memory

Memory Backend

Uses in-memory DashMap with a background cleanup task that runs every 10 seconds to remove expired entries. Fast but node-local - each Sockudo instance tracks limits independently.

Redis Backend

Uses Redis sorted sets (ZSET) for a true sliding window. The algorithm:

  1. Remove entries older than the window: ZREMRANGEBYSCORE
  2. Count current entries: ZCARD
  3. If under the limit, add the current timestamp: ZADD
  4. Set key expiry: EXPIRE

This provides cluster-wide rate limiting - all Sockudo nodes share the same counters.

{
  "rate_limiter": {
    "driver": "redis",
    "redis": {
      "prefix": "sockudo_rl:",
      "url_override": null,
      "cluster_mode": false
    }
  }
}
SettingEnv VarDefaultDescription
prefixRATE_LIMITER_REDIS_PREFIXsockudo_rl:Redis key prefix
url_overridenullOverride Redis URL
cluster_modefalseUse cluster-aware connections

Proxy Trust (trust_hops)

When Sockudo runs behind a reverse proxy or load balancer, client IPs appear as the proxy's IP. The trust_hops setting controls how many X-Forwarded-For hops to trust:

ValueBehavior
0Use the direct connection IP (default, safest)
1Trust one proxy hop (e.g., single load balancer)
2Trust two hops (e.g., CDN + load balancer)
# Behind one load balancer
RATE_LIMITER_API_TRUST_HOPS=1
Setting trust_hops too high allows clients to spoof their IP by adding fake X-Forwarded-For headers. Only trust the exact number of proxies in your infrastructure.

Response Headers

When rate limiting is active, responses include standard rate limit headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1707744060

When the limit is exceeded:

HTTP/1.1 429 Too Many Requests
Retry-After: 45

Choosing a Driver

ScenarioRecommended Driver
Single-node, developmentmemory
Multi-node productionredis
Rate limiting not needednone

For multi-node deployments, the memory driver means each node enforces limits independently. A client could hit Node A 100 times and Node B 100 times, effectively doubling the limit. Use redis for consistent cluster-wide enforcement.

Copyright © 2026