Limits

The limits block configures request/response limits, connection limits, and rate limiting. These settings are critical for predictable behavior, resource protection, and “sleepable operations.”

Basic Configuration

limits {
    max-header-size-bytes 8192
    max-header-count 100
    max-body-size-bytes 10485760  // 10MB
}

Header Limits

limits {
    max-header-size-bytes 8192     // Total headers size
    max-header-count 100           // Maximum header count
    max-header-name-bytes 256      // Per-header name size
    max-header-value-bytes 4096    // Per-header value size
}
SettingDefaultDescription
max-header-size-bytes8192 (8KB)Total size of all headers
max-header-count100Maximum number of headers
max-header-name-bytes256Maximum header name length
max-header-value-bytes4096 (4KB)Maximum header value length

Security note: Large header limits can be exploited for denial-of-service. Keep defaults unless you have specific requirements.

Environmentheader-sizeheader-countheader-value
Production4096-819250-1002048-4096
Development163842008192
API Gateway81921004096

Body Limits

limits {
    max-body-size-bytes 10485760       // 10MB - maximum request body
    max-body-buffer-bytes 1048576      // 1MB - buffer for inspection
    max-body-inspection-bytes 1048576  // 1MB - bytes sent to agents
}
SettingDefaultDescription
max-body-size-bytes10485760 (10MB)Maximum request body size
max-body-buffer-bytes1048576 (1MB)Maximum buffered body size
max-body-inspection-bytes1048576 (1MB)Maximum body sent to agents

Body Size Guidelines

Use CaseRecommended Size
API endpoints1-10 MB
File uploads100 MB - 1 GB
JSON APIs1-5 MB
Form submissions1-10 MB

Memory impact: max-body-buffer-bytes × max-in-flight-requests = potential memory usage for body buffering.

Per-Route Body Limits

Override body limits on specific routes:

routes {
    route "upload" {
        matches {
            path-prefix "/upload/"
        }
        upstream "storage"
        policies {
            max-body-size "500MB"
        }
    }

    route "api" {
        matches {
            path-prefix "/api/"
        }
        upstream "backend"
        policies {
            max-body-size "1MB"
        }
    }
}

Decompression Limits

Protect against decompression bombs:

limits {
    max-decompression-ratio 100.0       // Max 100:1 compression ratio
    max-decompressed-size-bytes 104857600  // 100MB decompressed
}
SettingDefaultDescription
max-decompression-ratio100.0Maximum compression ratio allowed
max-decompressed-size-bytes104857600 (100MB)Maximum decompressed size

Security note: Compression bombs (zip bombs) can use 1KB of compressed data to expand to gigabytes. These limits prevent resource exhaustion.

Connection Limits

limits {
    max-connections-per-client 100
    max-connections-per-route 1000
    max-total-connections 10000
    max-idle-connections-per-upstream 100
}
SettingDefaultDescription
max-connections-per-client100Per-client connection limit
max-connections-per-route1000Per-route connection limit
max-total-connections10000Global connection limit
max-idle-connections-per-upstream100Idle connections per upstream

Connection Limit Sizing

Deploymentper-clientper-routetotal
Small505005000
Medium100100010000
Large200200050000
API Gateway1005000100000

Formula: max-total-connections should be less than or equal to OS file descriptor limit minus a safety margin.

Check your limits:

ulimit -n  # Current soft limit
cat /proc/sys/fs/file-max  # System limit

Request Limits

limits {
    max-in-flight-requests 10000
    max-in-flight-requests-per-worker 1000
    max-queued-requests 1000
}
SettingDefaultDescription
max-in-flight-requests10000Total concurrent requests
max-in-flight-requests-per-worker1000Per-worker concurrent requests
max-queued-requests1000Pending requests in queue

When limits are reached:

  • New requests receive 503 Service Unavailable
  • Retry-After header indicates when to retry

Agent Limits

limits {
    max-agent-queue-depth 100
    max-agent-body-bytes 1048576     // 1MB to agents
    max-agent-response-bytes 10240   // 10KB from agents
}
SettingDefaultDescription
max-agent-queue-depth100Pending requests per agent
max-agent-body-bytes1048576 (1MB)Request body sent to agents
max-agent-response-bytes10240 (10KB)Response size from agents

These limits protect the proxy from misbehaving agents and ensure bounded memory usage.

Rate Limiting

Global Rate Limits

limits {
    max-requests-per-second-global 10000
}

Global limit applies across all clients and routes.

Per-Client Rate Limits

limits {
    max-requests-per-second-per-client 100
}

Limits requests per unique client IP address.

Per-Route Rate Limits

limits {
    max-requests-per-second-per-route 1000
}

Limits total requests to each route.

Rate Limit Behavior

Rate limiting uses token bucket algorithm:

  • Burst capacity: 10× the per-second limit
  • Refill rate: Continuous refill at configured rate
  • Response: 429 Too Many Requests with Retry-After header

Example:

limits {
    max-requests-per-second-per-client 100
}
  • Burst: 1000 requests
  • Sustained: 100 requests/second
  • Over limit: 429 response, retry in ~1 second

Route-Level Rate Limits

For fine-grained control, configure rate limits per route:

routes {
    route "api" {
        matches {
            path-prefix "/api/"
        }
        upstream "backend"
        policies {
            rate-limit {
                requests-per-second 100
                burst 500
                key "client_ip"  // or "header:X-API-Key"
            }
        }
    }
}

Rate limit keys:

  • client_ip - Client IP address
  • header:X-API-Key - Header value
  • path - Request path
  • route - Route ID

Memory Limits

limits {
    max-memory-bytes 2147483648     // 2GB hard limit
    max-memory-percent 80.0         // 80% of system memory
}
SettingDefaultDescription
max-memory-bytesNoneAbsolute memory limit
max-memory-percentNonePercentage of system memory

When memory limits are reached:

  1. New connections are rejected
  2. Request queues are flushed
  3. Alert is raised via metrics/logs

Profile Presets

Development

limits {
    // Permissive for testing
    max-header-size-bytes 16384
    max-header-count 200
    max-body-size-bytes 104857600  // 100MB
    max-in-flight-requests 100000

    // No rate limits
    max-requests-per-second-global null
    max-requests-per-second-per-client null
}

Production (Conservative)

limits {
    // Restrictive headers
    max-header-size-bytes 4096
    max-header-count 50
    max-header-name-bytes 128
    max-header-value-bytes 2048

    // Limited body
    max-body-size-bytes 1048576  // 1MB
    max-body-buffer-bytes 524288 // 512KB

    // Connection protection
    max-connections-per-client 50
    max-total-connections 5000
    max-in-flight-requests 5000

    // Rate limiting
    max-requests-per-second-global 10000
    max-requests-per-second-per-client 100

    // Memory protection
    max-memory-percent 80.0
}

High-Traffic API

limits {
    // Standard headers
    max-header-size-bytes 8192
    max-header-count 100

    // JSON payloads
    max-body-size-bytes 10485760  // 10MB

    // High throughput
    max-connections-per-client 200
    max-connections-per-route 5000
    max-total-connections 50000
    max-in-flight-requests 50000
    max-in-flight-requests-per-worker 5000

    // Rate limiting
    max-requests-per-second-global 100000
    max-requests-per-second-per-client 1000
}

Complete Example

limits {
    // Headers
    max-header-size-bytes 8192
    max-header-count 100
    max-header-name-bytes 256
    max-header-value-bytes 4096

    // Bodies
    max-body-size-bytes 10485760
    max-body-buffer-bytes 1048576
    max-body-inspection-bytes 1048576

    // Decompression protection
    max-decompression-ratio 100.0
    max-decompressed-size-bytes 104857600

    // Connections
    max-connections-per-client 100
    max-connections-per-route 1000
    max-total-connections 10000
    max-idle-connections-per-upstream 100

    // Requests
    max-in-flight-requests 10000
    max-in-flight-requests-per-worker 1000
    max-queued-requests 1000

    // Agents
    max-agent-queue-depth 100
    max-agent-body-bytes 1048576
    max-agent-response-bytes 10240

    // Rate limiting
    max-requests-per-second-global 10000
    max-requests-per-second-per-client 100
    max-requests-per-second-per-route 1000

    // Memory
    max-memory-percent 80.0
}

Default Values Summary

CategorySettingDefault
Headersmax-header-size-bytes8192
max-header-count100
max-header-name-bytes256
max-header-value-bytes4096
Bodiesmax-body-size-bytes10485760 (10MB)
max-body-buffer-bytes1048576 (1MB)
max-body-inspection-bytes1048576 (1MB)
Decompressionmax-decompression-ratio100.0
max-decompressed-size-bytes104857600 (100MB)
Connectionsmax-connections-per-client100
max-connections-per-route1000
max-total-connections10000
max-idle-connections-per-upstream100
Requestsmax-in-flight-requests10000
max-in-flight-requests-per-worker1000
max-queued-requests1000
Agentsmax-agent-queue-depth100
max-agent-body-bytes1048576 (1MB)
max-agent-response-bytes10240 (10KB)
Rate LimitsAll rate limitsNone (disabled)
MemoryMemory limitsNone (disabled)

Monitoring Limits

Metrics

Sentinel exposes limit-related metrics:

sentinel_header_size_exceeded_total
sentinel_body_size_exceeded_total
sentinel_connection_limit_reached_total
sentinel_rate_limit_exceeded_total
sentinel_memory_usage_bytes
sentinel_connections_active
sentinel_requests_in_flight

Logging

Limit violations are logged at WARN level:

{
  "level": "WARN",
  "message": "Request body size exceeded limit",
  "limit": 10485760,
  "actual": 15728640,
  "client_ip": "10.0.0.5",
  "trace_id": "2kF8xQw4BnM"
}

Troubleshooting

413 Payload Too Large

Request body exceeds max-body-size-bytes:

# Check current limit
grep max-body-size sentinel.kdl

# Increase for specific route
route "upload" {
    policies {
        max-body-size "100MB"
    }
}

429 Too Many Requests

Rate limit exceeded:

# Check Retry-After header
curl -I https://api.example.com/endpoint
# Retry-After: 1

# Increase limits or implement client-side throttling

503 Service Unavailable (Connection Limit)

Connection or request limits reached:

  1. Check current connections: curl localhost:9090/admin/stats
  2. Review max-total-connections and max-in-flight-requests
  3. Check for connection leaks in clients

Next Steps